Add a variable to a class instance at runtime: Difference between revisions

Content added Content deleted
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 195: Line 195:
<pre>sampleObj.bar = 1
<pre>sampleObj.bar = 1
< Press any key ></pre>
< Press any key ></pre>



=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
Line 571: Line 570:
Wed Feb 23 21:33:50 CST 2011
Wed Feb 23 21:33:50 CST 2011
null</pre>
null</pre>

=={{header|Io}}==

All "instance variables" (or slots in Io nomenclature) are created at runtime.

<lang io>Empty := Object clone

e := Empty clone
e foo := 1</lang>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
Line 639: Line 629:
R_tempconstructor_1.d := 9
R_tempconstructor_1.d := 9
R_tempconstructor_1.e := 7</pre>
R_tempconstructor_1.e := 7</pre>

=={{header|Io}}==

All "instance variables" (or slots in Io nomenclature) are created at runtime.

<lang io>Empty := Object clone

e := Empty clone
e foo := 1</lang>


=={{header|J}}==
=={{header|J}}==
Line 779: Line 778:
put obj.bar
put obj.bar
-- "BAR"</lang>
-- "BAR"</lang>

=={{header|LOLCODE}}==
<tt>BUKKIT</tt>s (the all-purpose container type) can be added to at any point during execution, and the <tt>SRS</tt> operator permits the creation of identifiers from strings. This program and its output demonstrate both by prompting the user for a name and a value, modifying the object accordingly, and then printing the value of the new variable.
<lang LOLCODE>HAI 1.3

I HAS A object ITZ A BUKKIT
I HAS A name, I HAS A value

IM IN YR interface
VISIBLE "R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? "!
I HAS A option, GIMMEH option

option, WTF?
OMG "A"
VISIBLE "NAME: "!, GIMMEH name
VISIBLE "VALUE: "!, GIMMEH value
object HAS A SRS name ITZ value, GTFO
OMG "P"
VISIBLE "NAME: "!, GIMMEH name
VISIBLE object'Z SRS name
OIC
IM OUTTA YR interface

KTHXBYE</lang>
Example run:
<pre>R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? A
NAME: foo
VALUE: 42
R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? P
NAME: foo
42</pre>



=={{header|Logtalk}}==
=={{header|Logtalk}}==
Line 847: Line 814:
true
true
</lang>
</lang>

=={{header|LOLCODE}}==
<tt>BUKKIT</tt>s (the all-purpose container type) can be added to at any point during execution, and the <tt>SRS</tt> operator permits the creation of identifiers from strings. This program and its output demonstrate both by prompting the user for a name and a value, modifying the object accordingly, and then printing the value of the new variable.
<lang LOLCODE>HAI 1.3

I HAS A object ITZ A BUKKIT
I HAS A name, I HAS A value

IM IN YR interface
VISIBLE "R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? "!
I HAS A option, GIMMEH option

option, WTF?
OMG "A"
VISIBLE "NAME: "!, GIMMEH name
VISIBLE "VALUE: "!, GIMMEH value
object HAS A SRS name ITZ value, GTFO
OMG "P"
VISIBLE "NAME: "!, GIMMEH name
VISIBLE object'Z SRS name
OIC
IM OUTTA YR interface

KTHXBYE</lang>
Example run:
<pre>R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? A
NAME: foo
VALUE: 42
R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? P
NAME: foo
42</pre>


=={{header|Lua}}==
=={{header|Lua}}==
Line 1,191: Line 1,189:


</lang>
</lang>

=={{header|Oz}}==
=={{header|Oz}}==
It is not possible to add variables to instances in Oz. Every object has exactly one class and this association cannot be changed after object creation. Classes themselves are immutable.
It is not possible to add variables to instances in Oz. Every object has exactly one class and this association cannot be changed after object creation. Classes themselves are immutable.
Line 1,242: Line 1,241:
# Set runtime variable (key => value).
# Set runtime variable (key => value).
$o->{'foo'} = 1;</lang>
$o->{'foo'} = 1;</lang>


=={{header|Perl 6}}==
{{works with|Rakudo|2015.12}}
You can add variables/methods to a class at runtime by composing in a role. The role only affects that instance, though it is inheritable. An object created from an existing object will inherit any roles composed in with values set to those at the time the role was created. If you want to keep changed values in the new object, clone it instead.
<lang perl6>class Bar { } # an empty class

my $object = Bar.new; # new instance

role a_role { # role to add a variable: foo,
has $.foo is rw = 2; # with an initial value of 2
}

$object does a_role; # compose in the role

say $object.foo; # prints: 2
$object.foo = 5; # change the variable
say $object.foo; # prints: 5

my $ohno = Bar.new; # new Bar object
#say $ohno.foo; # runtime error, base Bar class doesn't have the variable foo

my $this = $object.new; # instantiate a new Bar derived from $object
say $this.foo; # prints: 2 - original role value

my $that = $object.clone; # instantiate a new Bar derived from $object copying any variables
say $that.foo; # 5 - value from the cloned object</lang>
That's what's going on underneath, but often people just mix in an anonymous role directly using the <tt>but</tt> operator. Here we'll mix an attribute into a normal integer.
<lang perl6>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }

say $lue; # 42
say $lue.answer; # Life, the Universe, and Everything</lang>
On the other hand, mixins are frowned upon when it is possible to compose roles directly into classes (as with Smalltalk traits), so that you get method collision detection at compile time. If you want to change a class at run time, you can also use monkey patching:

<lang perl6>use MONKEY-TYPING;
augment class Int {
method answer { "Life, the Universe, and Everything" }
}
say 42.answer; # Life, the Universe, and Everything</lang>
This practice, though allowed, is considered to be Evil Action at a Distance.


=={{header|Phix}}==
=={{header|Phix}}==
Line 1,461: Line 1,420:
# >>> whatever</lang>
# >>> whatever</lang>
:Note: The name ''self'' is not special; it's merely the pervasive Python convention. In this example I've deliberately used ''this'' in the class definition to underscore this fact. The nested definition could use any name for the "self" object. Because it's nested the value of the object is evaluated at the time that the patch_empty() function is run and thus the function being patched in has a valid reference to the object into which it is being inserted. Other arguments could be passed as necessary. Such techniques are not recommended; however they are possible.
:Note: The name ''self'' is not special; it's merely the pervasive Python convention. In this example I've deliberately used ''this'' in the class definition to underscore this fact. The nested definition could use any name for the "self" object. Because it's nested the value of the object is evaluated at the time that the patch_empty() function is run and thus the function being patched in has a valid reference to the object into which it is being inserted. Other arguments could be passed as necessary. Such techniques are not recommended; however they are possible.

=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2015.12}}
You can add variables/methods to a class at runtime by composing in a role. The role only affects that instance, though it is inheritable. An object created from an existing object will inherit any roles composed in with values set to those at the time the role was created. If you want to keep changed values in the new object, clone it instead.
<lang perl6>class Bar { } # an empty class

my $object = Bar.new; # new instance

role a_role { # role to add a variable: foo,
has $.foo is rw = 2; # with an initial value of 2
}

$object does a_role; # compose in the role

say $object.foo; # prints: 2
$object.foo = 5; # change the variable
say $object.foo; # prints: 5

my $ohno = Bar.new; # new Bar object
#say $ohno.foo; # runtime error, base Bar class doesn't have the variable foo

my $this = $object.new; # instantiate a new Bar derived from $object
say $this.foo; # prints: 2 - original role value

my $that = $object.clone; # instantiate a new Bar derived from $object copying any variables
say $that.foo; # 5 - value from the cloned object</lang>
That's what's going on underneath, but often people just mix in an anonymous role directly using the <tt>but</tt> operator. Here we'll mix an attribute into a normal integer.
<lang perl6>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }

say $lue; # 42
say $lue.answer; # Life, the Universe, and Everything</lang>
On the other hand, mixins are frowned upon when it is possible to compose roles directly into classes (as with Smalltalk traits), so that you get method collision detection at compile time. If you want to change a class at run time, you can also use monkey patching:

<lang perl6>use MONKEY-TYPING;
augment class Int {
method answer { "Life, the Universe, and Everything" }
}
say 42.answer; # Life, the Universe, and Everything</lang>
This practice, though allowed, is considered to be Evil Action at a Distance.


=={{header|REBOL}}==
=={{header|REBOL}}==