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

m
syntax highlighting fixup automation
(Added Arturo implementation)
m (syntax highlighting fixup automation)
Line 7:
=={{header|ActionScript}}==
In ActionScript this can be done using an Object object
<langsyntaxhighlight lang=actionscript>var object:Object = new Object();
object.foo = "bar";</langsyntaxhighlight>
Or by creating a dynamic class
<langsyntaxhighlight lang=actionscript>package
{
public dynamic class Foo
Line 16:
// ...
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang=actionscript>var foo:Foo = new Foo();
foo.bar = "zap";</langsyntaxhighlight>
 
=={{header|Ada}}==
Ada is not a dynamically typed language. Yet it supports mix-in inheritance, run-time inheritance and interfaces. These three allow us to achieve the desired effect, however questionably useful it could be. The example declares an interface of the class (Class). Then a concrete type is created (Base). The object E is an instance of Base. Later, at the run time, a new type Monkey_Patch is created such that it refers to E and implements the class interface per delegation to E. Monkey_Patch has a new integer member Foo and EE is an instance of Monkey_Path. For the user EE appears as E with Foo.
<langsyntaxhighlight lang=ada>with Ada.Text_IO; use Ada.Text_IO;
 
procedure Dynamic is
Line 61:
Put_Line (EE.Boo & " with" & Integer'Image (EE.Foo));
end;
end Dynamic;</langsyntaxhighlight>
Sample output:
<pre>
Line 69:
=={{header|Arturo}}==
 
<langsyntaxhighlight lang=rebol>define :myClass [name,surname][]
 
myInstance: to :myClass ["John" "Doe"]
Line 75:
 
myInstance\age: 35
print myInstance</langsyntaxhighlight>
 
{{out}}
Line 84:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<langsyntaxhighlight lang=AutoHotkey>e := {}
e.foo := 1 </langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
It's not really intended that you should do this, but if you must you can:
<langsyntaxhighlight lang=bbcbasic> INSTALL @lib$+"CLASSLIB"
REM Create a base class with no members:
Line 120:
IF EVAL("FNassign(" + v$ + "," + n$ + ")")
ENDPROC
DEF FNassign(RETURN n, v) : n = v : = 0</langsyntaxhighlight>
 
=={{header|Bracmat}}==
This solution saves the original members and methods in a variable, using pattern matching. Then, using macro expansion, a new object is created with an additional member variable and also an additional method. Because the new object is assigned to the same variable as the original object, the original object ceases to exist.
<langsyntaxhighlight lang=bracmat>( ( struktuur
= (aMember=) (aMethod=.!(its.aMember))
)
Line 149:
& out$("aMember contains:" (object..aMethod)$)
& out$("anotherMember contains:" (object..anotherMethod)$)
&);</langsyntaxhighlight>
Output:
<langsyntaxhighlight lang=bracmat>Object as originally created:
(object=
=(aMember=) (aMethod=.!(its.aMember)));
Line 165:
Call both methods and output their return values.
aMember contains: A value
anotherMember contains: some other value</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|4.0}}
<langsyntaxhighlight lang=csharp>// ----------------------------------------------------------------------------------------------
//
// Program.cs - DynamicClassVariable
Line 205:
#endregion
}
}</langsyntaxhighlight>
 
{{out}}
Line 212:
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang=coffeescript># CoffeeScript is dynamic, just like the Javascript it compiles to.
# You can dynamically add attributes to objects.
 
Line 230:
e.yo = -> "baz"
console.log e.foo, e.yo()
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 238:
{{libheader|Closer to MOP}}
 
<langsyntaxhighlight lang=lisp>(defun augment-instance-with-slots (instance slots)
(change-class instance
(make-instance 'standard-class
:direct-superclasses (list (class-of instance))
:direct-slots slots)))</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang=lisp>CL-USER> (let* ((instance (make-instance 'foo :bar 42 :baz 69))
(new-slots '((:name xenu :initargs (:xenu)))))
(augment-instance-with-slots instance new-slots)
Line 257:
BAR = 42
BAZ = 69
XENU = 666</langsyntaxhighlight>
 
The following REPL transcript (from [[LispWorks]]) shows the definition of a class <code>some-class</code> with no slots, and the creation of an instance of the class. The first attempt to access the slot named <code>slot1</code> signals an error as there is no such slot. Then the class is redefined to have such a slot, and with a default value of 23. Attempting to access the slot in the preëxisting instance now gives the default value, since the slot has been added to the instance. This behavior is specified in [http://www.lispworks.com/documentation/HyperSpec/Body/04_cf.htm §4.3.6 Redefining Classes] of the [http://www.lispworks.com/documentation/HyperSpec/Front/index.htm HyperSpec].
Line 286:
 
=={{header|D}}==
<langsyntaxhighlight lang=d>struct Dynamic(T) {
private T[string] vars;
 
Line 316:
writeln(d2.a, " ", d2.b, " ", d2.c);
immutable int x = d2.b.get!int;
}</langsyntaxhighlight>
{{out}}
<pre>10.5 20.2
Hello 11 ['x':2, 'y':4]</pre>
If you want Dynamic to be a class the code is similar. If the attribute names aren't known at compile-time, you have to use a more normal syntax:
<langsyntaxhighlight lang=d>import std.stdio, std.variant, std.conv;
 
struct Dyn {
Line 333:
d[attribute_name] = "something";
writeln(d[attribute_name]);
}</langsyntaxhighlight>
{{out}}
<pre>something</pre>
Line 341:
 
ELENA 4.x:
<langsyntaxhighlight lang=elena>import extensions;
 
class Extender : BaseExtender
Line 365:
 
console.readChar()
}</langsyntaxhighlight>
{{out}}
<pre>
Line 376:
'''Array:'''
In this example we add a function (which prints out the content of the array) and a new value. While we are not technically adding a "variable", this example is presented to show similar type of functionality.
<langsyntaxhighlight lang=falcon>vect = [ 'alpha', 'beta', 'gamma' ]
vect.dump = function ()
for n in [0: self.len()]
Line 383:
end
vect += 'delta'
vect.dump()</langsyntaxhighlight>
Output from the above:
<langsyntaxhighlight lang=falcon>0: alpha
1: beta
2: gamma
3: delta</langsyntaxhighlight>
'''Dictionary:'''
In this example we will add a variable through the use of an object from a bless'ed dictionary. We create a new variable called 'newVar' at runtime and assign a string to it. Additionally we assign an external, to the object, function (sub_func) to the variable 'sub'.
<langsyntaxhighlight lang=falcon>function sub_func( value )
self['prop'] -= value
return self.prop
Line 405:
])
 
dict[ 'newVar' ] = "I'm Rich In Data"</langsyntaxhighlight>
 
=={{header|FBSL}}==
FBSL class instances aren't expandable with additional, directly accessible public methods at runtime once the class template is defined in the user code. But FBSL has an extremely powerful feature -- an ExecLine() function -- which permits the user to execute any additional code on the fly either privately (bypassing the main code flow) or publicly (interacting with the main code). ExecLine() can be used for a variety of applications from the fine-tuning of current tasks to designing application plug-ins or completely standalone code debuggers. The following class instance may be stuffed up at runtime with any code from simple variables to executable private methods and properties.
<langsyntaxhighlight lang=qbasic>#APPTYPE CONSOLE
 
CLASS Growable
Line 439:
PRINT Sponge.Yield()
 
PAUSE</langsyntaxhighlight>
'''Output:'''
1234567890
Line 451:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<langsyntaxhighlight lang=forth>include FMS-SI.f
include FMS-SILib.f
 
Line 481:
 
main \ => Now is the time 3.14159
</syntaxhighlight>
</lang>
 
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang=freebasic>
' Class ... End Class
' Esta característica aún no está implementada en el compilador.
</syntaxhighlight>
</lang>
 
 
Line 499:
 
However, as in the case of Groovy and Kotlin, we can ''make it appear'' as though fields are being added at runtime by using the built-in map type. For example:
<langsyntaxhighlight lang=go>package main
 
import (
Line 547:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 568:
 
Any [[Groovy]] class that implements "''Object get(String)''" and "''void set(String, Object)''" will have the '''apparent''' capability to add new properties. However, this capability will only work as expected with an appropriate implementation, backed by a Map object or something very much like a Map.
<langsyntaxhighlight lang=groovy>class A {
final x = { it + 25 }
private map = new HashMap()
Object get(String key) { map[key] }
void set(String key, Object value) { map[key] = value }
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang=groovy>def a = new A()
a.y = 55
a.z = { println (new Date()); Thread.sleep 5000 }
Line 584:
(0..2).each(a.z)
 
println a.q</langsyntaxhighlight>
 
Output:
Line 599:
 
''Note:'' Unicon can be translated via a command line switch into icon which allows for classes to be shared with Icon code (assuming no other incompatibilities exist).
<langsyntaxhighlight lang=unicon>
link ximage
 
Line 626:
x[newvars[i]] := newvals[i] # add new vars = values
return x
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 657:
All "instance variables" (or slots in Io nomenclature) are created at runtime.
 
<langsyntaxhighlight lang=io>Empty := Object clone
 
e := Empty clone
e foo := 1</langsyntaxhighlight>
 
=={{header|J}}==
If you assign a value to the name which references a property of a class instance, that name within that instance gets that value.
 
<langsyntaxhighlight lang=j> C=:<'exampleclass' NB. this will be our class name
V__C=: 0 NB. ensure the class exists
OBJ1=:conew 'exampleclass' NB. create an instance of our class
Line 677:
0
W__OBJ2 NB. our other instance does not
|value error</langsyntaxhighlight>
 
=={{header|JavaScript}}==
This kind of thing is fundamental to JavaScript, as it's a prototype-based language rather than a class-based one.
<langsyntaxhighlight lang=javascript>e = {} // generic object
e.foo = 1
e["bar"] = 2 // name specified at runtime</langsyntaxhighlight>
 
=={{header|jq}}==
jq's "+" operator can be used to add a key/value pair (or to add multiple key-value pairs) to an existing object at runtime, but
jq is a functional programming language, and objects themselves cannot be altered. Thus it may be helpful to introduce a variable, since the value of a variable can in effect be updated. For example:
<langsyntaxhighlight lang=jq>{"a":1} as $a | ($a + {"b":2}) as $a | $a
</langsyntaxhighlight>Thus the value of $a has undergone the desired transition, that is, its final value is {"a":1, "b":2}.
 
A Javascript-like syntax can also be used to add (or update) a key, for example:<langsyntaxhighlight lang=jq>$a|.c = 3
# or equivalently:
$a|.["c"] = 3</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 702:
For example, consider the below JSON input data for a program processing phone numbers,
where the type of phone numbers for the person is unknown until run-time:
<langsyntaxhighlight lang=xml>
{"phoneNumbers": [
{
Line 716:
"number": "123 456-7890"
}]}
</syntaxhighlight>
</lang>
Add the data into a class member that is declared as a Dict structure:
<langsyntaxhighlight lang=Julia>
mutable struct Contact
name::String
Line 726:
person = Contact("Jane Doe", Dict())
person.phonenumber["home"] = "212 555-1234"
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 733:
However, as in the case of Groovy, we can ''make it appear'' as though variables are being added at runtime by using a Map or similar structure. For example:
 
<langsyntaxhighlight lang=scala>// version 1.1.2
 
class SomeClass {
Line 762:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 783:
 
Latitude is prototype-oriented, so adding slots at runtime is very straightforward and common.
<langsyntaxhighlight lang=Latitude>myObject := Object clone.
 
;; Name known at compile-time.
Line 789:
 
;; Name known at runtime.
myObject slot 'foo = "bar".</langsyntaxhighlight>
 
=={{header|Lingo}}==
<langsyntaxhighlight lang=Lingo>obj = script("MyClass").new()
 
put obj.foo
Line 800:
obj.setProp(#bar, "BAR")
put obj.bar
-- "BAR"</langsyntaxhighlight>
 
=={{header|Logtalk}}==
Line 807:
The following example uses a prototype for simplicity.
 
<langsyntaxhighlight lang=logtalk>
% we start by defining an empty object
:- object(foo).
Line 826:
 
:- end_category.
</syntaxhighlight>
</lang>
 
We can test our example by compiling and loading the two entities above and then querying the object:
 
<langsyntaxhighlight lang=logtalk>
| ?- foo::bar(X).
X = 1 ;
Line 836:
X = 3
true
</syntaxhighlight>
</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.
<langsyntaxhighlight lang=LOLCODE>HAI 1.3
 
I HAS A object ITZ A BUKKIT
Line 860:
IM OUTTA YR interface
 
KTHXBYE</langsyntaxhighlight>
Example run:
<pre>R U WANTIN 2 (A)DD A VAR OR (P)RINT 1? A
Line 870:
 
=={{header|Lua}}==
<langsyntaxhighlight lang=lua>empty = {}
empty.foo = 1</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Adding y member to an object with a x member which made by a class alfa (a global function). We can make m as a copy of this new group (which is in a container, in a(3)). We can make a pointer to A(3) and handle the new member.
 
<langsyntaxhighlight lang=M2000 Interpreter>
Module checkit {
class alfa {
Line 909:
}
checkit
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica doesn't rally have classes, so it doesn't have class variables. However, many rules can be applied to a single tag, so it has some aspects similar to a class. With that definition, adding a class variable is similar to adding a rule:
<langsyntaxhighlight lang=Mathematica>
f[a]=1;
f[b]=2;
f[a]=3;
? f</langsyntaxhighlight>
Output:
Global`f
Line 928:
 
If the name of the variable to add is known at compile time, then this is just standard class construction:
<langsyntaxhighlight lang=MiniScript>empty = {}
empty.foo = 1</langsyntaxhighlight>
 
If the name of the variable to add is itself in a variable, then instead of dot syntax, use normal indexing:
 
<langsyntaxhighlight lang=MiniScript>empty = {}
varName = "foo"
empty[varName] = 1</langsyntaxhighlight>
 
Either method results in a perfectly ordinary class or instance (there is no technical distinction between these in MiniScript), which can be used as usual by subsequent code.
Line 941:
=={{header|Morfa}}==
To emulate adding a variable to a class instance, Morfa uses user-defined operators <tt>`</tt> and <tt>&lt;-</tt>.
<langsyntaxhighlight lang=morfa>
import morfa.base;
 
Line 1,004:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,011:
 
=={{header|Nim}}==
<langsyntaxhighlight lang=nim>import json
{.experimental: "dotOperators".}
template `.=`(js: JsonNode, field: untyped, value: untyped) =
Line 1,020:
echo(obj.foo)
obj.key = 3
echo(obj.key)</langsyntaxhighlight>
{{out}}
<pre>
Line 1,032:
You can put associative references on any object. You can put multiple ones on the same object. They are indexed by a pointer key (typically the address of some dummy variable). You use the functions <code>objc_getAssociatedObject()</code> and <code>objc_setAssociatedObject</code> to get and set them, respectively.
 
<langsyntaxhighlight lang=objc>#import <Foundation/Foundation.h>
#import <objc/runtime.h>
 
Line 1,051:
}
return 0;
}</langsyntaxhighlight>
 
You can also use a selector as the key, since two selectors with the same content are guaranteed to be equal:
<langsyntaxhighlight lang=objc>#import <Foundation/Foundation.h>
#import <objc/runtime.h>
 
Line 1,071:
}
return 0;
}</langsyntaxhighlight>
 
=={{header|Octave}}==
Octave is dynamically typed, and can have fields added in two methods:
 
<langsyntaxhighlight lang=octave>
% Given struct "test"
test.b=1;
test = setfield (test, "c", 3);
</syntaxhighlight>
</lang>
 
=={{header|ooRexx}}==
Line 1,086:
===Unknown Method Access===
This example traps unknown method calls, then sets or retrieves the values in an encapsulated directory object.
<langsyntaxhighlight lang=ooRexx>
d = .dynamicvar~new
d~foo = 123
Line 1,125:
self~init:.dynamicvar
 
</syntaxhighlight>
</lang>
 
===Dynamic Method Definitions===
An object may be written that can dynamically add methods to itself. This example is similar to the above example, but the UNKNOWN method attaches a getter/setter pair of methods for the name triggering the UNKNOWN call. On all subsequent calls, the attribute methods will get called.
<langsyntaxhighlight lang=ooRexx>
d = .dynamicvar~new
d~foo = 123
Line 1,166:
forward to(self) message(messageName) arguments(arguments)
 
</syntaxhighlight>
</lang>
 
=={{header|OxygenBasic}}==
Simple implementation for making runtime members - supports integer, float and string types.
<langsyntaxhighlight lang=oxygenbasic>
'=================
class fleximembers
Line 1,242:
a.delete
 
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
Line 1,249:
However, classes are also first-class values and are created at runtime. Many of the tasks that are solved with "monkeypatching" in other languages, can be solved by dynamically creating classes in Oz.
 
<langsyntaxhighlight lang=oz>declare
%% Creates a new class derived from BaseClass
%% with an added feature (==public immutable attribute)
Line 1,277:
in
{Show Instance.bar} %% inherited feature
{Show Instance.foo} %% feature of "synthesized" class</langsyntaxhighlight>
 
To add a variable number of features and attributes, you can use [http://www.mozart-oz.org/documentation/base/class.html Class.new].
Line 1,283:
=={{header|Perl}}==
{{works with|Perl|5.x}}
<langsyntaxhighlight lang=perl>package Empty;
 
# Constructor. Object is hash.
Line 1,294:
 
# Set runtime variable (key => value).
$o->{'foo'} = 1;</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 1,301:
Attempting to fetch/store "jelly" on a non-dynamic class would trigger a fatal error, unless said field had been explictly defined.
Needs 0.8.1+
<!--<langsyntaxhighlight lang=Phix>-->
<span style="color: #008080;">class</span> <span style="color: #000000;">wobbly</span> <span style="color: #000000;">dynamic</span>
<span style="color: #000080;font-style:italic;">-- (pre-define a few fields/methods if you like)</span>
Line 1,310:
<span style="color: #000000;">wobble<span style="color: #0000FF;">.<span style="color: #000000;">jelly</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"green"</span>
<span style="color: #0000FF;">?<span style="color: #000000;">wobble<span style="color: #0000FF;">.<span style="color: #000000;">jelly</span> <span style="color: #000080;font-style:italic;">-- "green"
<!--</langsyntaxhighlight>-->
 
=={{header|PHP}}==
<langsyntaxhighlight lang=php>class E {};
 
$e=new E();
Line 1,321:
$e->{"foo"} = 1; // using a runtime name
$x = "foo";
$e->$x = 1; // using a runtime name in a variable</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
In general, all instance variables in PicoLisp are dynamically created at
runtime.
<langsyntaxhighlight lang=PicoLisp>: (setq MyObject (new '(+MyClass))) # Create some object
-> $385605941
: (put MyObject 'newvar '(some value)) # Set variable
Line 1,333:
$385605941 (+MyClass)
newvar (some value)
-> $385605941</langsyntaxhighlight>
 
=={{header|Pike}}==
Pike does not allow adding variables to existing objects, but we can design a class that allows us to add variables.
<langsyntaxhighlight lang=Pike>class CSV
{
mapping variables = ([]);
Line 1,368:
"greeting"
})
</syntaxhighlight>
</lang>
 
=={{header|Pop11}}==
Line 1,389:
it using the 'pop11_compile' procedure.
 
<langsyntaxhighlight lang=pop11>lib objectclass;
 
define :class foo;
Line 1,416:
met1(bar) => ;;; default value -- false
"baz" -> met1(bar);
met1(bar) => ;;; new value</langsyntaxhighlight>
 
=={{header|PowerShell}}==
PowerShell allows extending arbitrary object instances at runtime with the <code>Add-Member</code> cmdlet. The following example adds a property ''Title'' to an integer:
<langsyntaxhighlight lang=powershell>$x = 42 `
| Add-Member -PassThru `
NoteProperty `
Title `
"The answer to the question about life, the universe and everything"</langsyntaxhighlight>
Now that property can be accessed:
<pre>PS> $x.Title
Line 1,449:
=={{header|Python}}==
 
<langsyntaxhighlight lang=python>class empty(object):
pass
e = empty()</langsyntaxhighlight>
 
If the variable (attribute) name is known at "compile" time (hard-coded):
 
<langsyntaxhighlight lang=python> e.foo = 1</langsyntaxhighlight>
 
If the variable name is determined at runtime:
<langsyntaxhighlight lang=python> setattr(e, name, value)</langsyntaxhighlight>
 
'''Note:''' Somewhat counter-intuitively one cannot simply use ''e = object(); e.foo = 1'' because the Python base ''object'' (the ultimate ancestor to all new-style classes) will raise attribute exceptions. However, any normal derivatives of ''object'' can be "monkey patched" at will.
Line 1,464:
Because functions are first class objects in Python one can not only add variables to instances. One can add or replace functionality to an instance. Doing so is tricky if one wishes to refer back to other instance attributes since there's no "magic" binding back to "self." One trick is to dynamically define the function to be added, nested within the function that applies the patch like so:
 
<langsyntaxhighlight lang=python>class empty(object):
def __init__(this):
this.foo = "whatever"
Line 1,476:
patch_empty(e)
e.print_output()
# >>> whatever</langsyntaxhighlight>
: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.
 
Line 1,483:
{{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.
<langsyntaxhighlight lang=perl6>class Bar { } # an empty class
 
my $object = Bar.new; # new instance
Line 1,504:
 
my $that = $object.clone; # instantiate a new Bar derived from $object copying any variables
say $that.foo; # 5 - value from the cloned object</langsyntaxhighlight>
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.
<langsyntaxhighlight 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</langsyntaxhighlight>
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:
 
<langsyntaxhighlight lang=perl6>use MONKEY-TYPING;
augment class Int {
method answer { "Life, the Universe, and Everything" }
}
say 42.answer; # Life, the Universe, and Everything</langsyntaxhighlight>
This practice, though allowed, is considered to be Evil Action at a Distance.
 
=={{header|REBOL}}==
<langsyntaxhighlight lang=rebol>
REBOL [
Title: "Add Variables to Class at Runtime"
Line 1,569:
print [crlf "Fighter squadron:"]
foreach pilot squadron [probe pilot]
</syntaxhighlight>
</lang>
 
=={{header|Red}}==
<langsyntaxhighlight lang=Red>person: make object! [
name: none
age: none
Line 1,582:
foreach person people [
print reduce [person/age "year old" person/name "is good at" any [select person 'skill "nothing"]]
]</langsyntaxhighlight>
 
=={{header|Ring}}==
We can add an attribute (or a group of attributes) to the object state using addattribute() function
<langsyntaxhighlight lang=ring>o1 = new point
addattribute(o1,"x")
addattribute(o1,"y")
addattribute(o1,"z")
see o1 {x=10 y=20 z=30}
class point</langsyntaxhighlight>
{{out}}
<pre>
Line 1,600:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang=ruby>class Empty
end
 
Line 1,612:
f = Empty.new
f.foo = 1 # raises NoMethodError
</syntaxhighlight>
</lang>
 
"class << e" uses the ''singleton class'' of "e", which is an automatic subclass of Empty that has only this single instance. Therefore we added the "foo" accessor only to "e", not to other instances of Empty.
Another way of adding a method to a singleton is:
<langsyntaxhighlight lang=ruby>yes_no = "Yes"
 
def yes_no.not
Line 1,625:
p yes_no.not # => "No"
p yes_no.not # => "Yes"
p "aaa".not # => undefined method `not' for "aaa":String (NoMethodError)</langsyntaxhighlight>
 
=={{header|Scala}}==
Line 1,631:
Since version 2.10 Scala supports dynamic types. Dynamic types have to implement trait ''Dynamic'' and implement methods ''selectDynamic'' and ''updateDynamic''.
 
<langsyntaxhighlight lang=scala>import language.dynamics
import scala.collection.mutable.HashMap
 
Line 1,642:
map(name) = value
}
}</langsyntaxhighlight>
 
Sample output in the REPL:
 
<langsyntaxhighlight lang=scala>scala> val a = new A
a: A = A@7b20f29d
 
Line 1,653:
 
scala> a.foo
res10: Any = 42</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang=ruby>class Empty{};
var e = Empty(); # create a new class instance
e{:foo} = 42; # add variable 'foo'
say e{:foo}; # print the value of 'foo'</langsyntaxhighlight>
 
=={{header|Slate}}==
Slate objects are prototypes:
<langsyntaxhighlight lang=slate>define: #Empty -> Cloneable clone.
define: #e -> Empty clone.
e addSlotNamed: #foo valued: 1.</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
Line 1,671:
This preserves object identity. (by the way: if we remember and reuse these temp classes, we get the core of Google's fast JavaScript interpreter implementation ;-)
{{works with|Smalltalk/X}} (should work with all Smalltalks, though)
<langsyntaxhighlight lang=smalltalk>|addSlot p|
 
addSlot :=
Line 1,686:
newObj := anonCls cloneFrom:obj.
obj become:newObj.
].</langsyntaxhighlight>
create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
<langsyntaxhighlight lang=smalltalk>p := Point x:10 y:20.
addSlot value:p value:'z'.
p z:30.
p z.
p z:40.
p inspect</langsyntaxhighlight>
 
The above used a block to perform this operation in privacy. In a real world application, the addSlot code would be added as an extension to the Object class, as in.
<langsyntaxhighlight lang=smalltalk>!Object methodsFor:'adding slots'!
 
addSlot: slotName
Line 1,710:
anonCls compile:('%1:v %1 := v' bindWith:slotName).
newObj := anonCls cloneFrom:self.
self become:newObj.</langsyntaxhighlight>
then, again create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
<langsyntaxhighlight lang=smalltalk>p := Point x:10 y:20.
p addSlot:'z'. "instance specific added slot"
p z:30.
Line 1,728:
p3 z:4.
p3 inspect. "shows 3 slots"
</langsyntaxhighlight>
 
<!--
Line 1,736:
CG: commented the bad example; maybe the original author wants to fix it / comment on it.
 
<langsyntaxhighlight lang=smalltalk>Object subclass: #Monkey
instanceVariableNames: 'aVar'
classVariableNames: ''
Line 1,793:
aMonkey setX: 10 .
aMonkey inspect .
(aMonkey x) printNl .</langsyntaxhighlight>
 
Output is:
Line 1,810:
We can use the same associated object mechanism as in Objective-C:
 
<langsyntaxhighlight lang=swift>import Foundation
let fooKey = UnsafeMutablePointer<UInt8>.alloc(1)
Line 1,825:
} else {
print("no associated object")
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
Line 1,831:
 
The code below uses the fact that each object is implemented as a namespace, to add a ''time'' variable to an instance of ''summation'':
<langsyntaxhighlight lang=Tcl>% package require TclOO
% oo::class create summation {
constructor {} {
Line 1,857:
% $s value time
now
%</langsyntaxhighlight>
An alternative approach is to expose the (normally hidden) <code>varname</code> method on the object so that you can get a handle for an arbitrary variable in the object.
<langsyntaxhighlight lang=tcl>% oo::class create summation {
constructor {} {
variable v 0
Line 1,886:
% # Show that it is only in one object...
% $s2 value time
can't read "time": no such variable</langsyntaxhighlight>
 
=={{header|Wren}}==
Although Wren is dynamically typed, it is not possible to add new variables (or fields as we prefer to call them) to a class at run time. We therefore follow the example of some of the other languages here and use a map field instead.
<langsyntaxhighlight lang=ecmascript>import "io" for Stdin, Stdout
 
class Birds {
Line 1,916:
for (kv in birds.userFields) {
System.print(" %(kv.key) = %(kv.value)")
}</langsyntaxhighlight>
 
{{out}}
Line 1,940:
 
=={{header|XBS}}==
<langsyntaxhighlight lang=xbs>set Object = {}
Object.Hello = "World";
log(Object.Hello);</langsyntaxhighlight>
{{out}}
<pre>
10,327

edits