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

Content added Content deleted
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 1: Line 1:
<nowiki>Insert non-formatted text here</nowiki>{{task|Object oriented}}
{{task|Object oriented}}


Demonstrate how to dynamically add variables to an object (a class instance) at runtime.
Demonstrate how to dynamically add variables to an object (a class instance) at runtime.
Line 7: Line 7:
=={{header|ActionScript}}==
=={{header|ActionScript}}==
In ActionScript this can be done using an Object object
In ActionScript this can be done using an Object object
<syntaxhighlight lang=actionscript>var object:Object = new Object();
<syntaxhighlight lang="actionscript">var object:Object = new Object();
object.foo = "bar";</syntaxhighlight>
object.foo = "bar";</syntaxhighlight>
Or by creating a dynamic class
Or by creating a dynamic class
<syntaxhighlight lang=actionscript>package
<syntaxhighlight lang="actionscript">package
{
{
public dynamic class Foo
public dynamic class Foo
Line 17: Line 17:
}
}
}</syntaxhighlight>
}</syntaxhighlight>
<syntaxhighlight lang=actionscript>var foo:Foo = new Foo();
<syntaxhighlight lang="actionscript">var foo:Foo = new Foo();
foo.bar = "zap";</syntaxhighlight>
foo.bar = "zap";</syntaxhighlight>


=={{header|Ada}}==
=={{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.
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.
<syntaxhighlight lang=ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;


procedure Dynamic is
procedure Dynamic is
Line 69: Line 69:
=={{header|Arturo}}==
=={{header|Arturo}}==


<syntaxhighlight lang=rebol>define :myClass [name,surname][]
<syntaxhighlight lang="rebol">define :myClass [name,surname][]


myInstance: to :myClass ["John" "Doe"]
myInstance: to :myClass ["John" "Doe"]
Line 84: Line 84:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
{{works with|AutoHotkey_L}}
<syntaxhighlight lang=AutoHotkey>e := {}
<syntaxhighlight lang="autohotkey">e := {}
e.foo := 1 </syntaxhighlight>
e.foo := 1 </syntaxhighlight>


Line 90: Line 90:
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
It's not really intended that you should do this, but if you must you can:
It's not really intended that you should do this, but if you must you can:
<syntaxhighlight lang=bbcbasic> INSTALL @lib$+"CLASSLIB"
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"CLASSLIB"
REM Create a base class with no members:
REM Create a base class with no members:
Line 124: Line 124:
=={{header|Bracmat}}==
=={{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.
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.
<syntaxhighlight lang=bracmat>( ( struktuur
<syntaxhighlight lang="bracmat">( ( struktuur
= (aMember=) (aMethod=.!(its.aMember))
= (aMember=) (aMethod=.!(its.aMember))
)
)
Line 151: Line 151:
&);</syntaxhighlight>
&);</syntaxhighlight>
Output:
Output:
<syntaxhighlight lang=bracmat>Object as originally created:
<syntaxhighlight lang="bracmat">Object as originally created:
(object=
(object=
=(aMember=) (aMethod=.!(its.aMember)));
=(aMember=) (aMethod=.!(its.aMember)));
Line 169: Line 169:
=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|4.0}}
{{works with|C sharp|C#|4.0}}
<syntaxhighlight lang=csharp>// ----------------------------------------------------------------------------------------------
<syntaxhighlight lang="csharp">// ----------------------------------------------------------------------------------------------
//
//
// Program.cs - DynamicClassVariable
// Program.cs - DynamicClassVariable
Line 212: Line 212:


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<syntaxhighlight lang=coffeescript># CoffeeScript is dynamic, just like the Javascript it compiles to.
<syntaxhighlight lang="coffeescript"># CoffeeScript is dynamic, just like the Javascript it compiles to.
# You can dynamically add attributes to objects.
# You can dynamically add attributes to objects.


Line 238: Line 238:
{{libheader|Closer to MOP}}
{{libheader|Closer to MOP}}


<syntaxhighlight lang=lisp>(defun augment-instance-with-slots (instance slots)
<syntaxhighlight lang="lisp">(defun augment-instance-with-slots (instance slots)
(change-class instance
(change-class instance
(make-instance 'standard-class
(make-instance 'standard-class
Line 246: Line 246:
Example:
Example:


<syntaxhighlight lang=lisp>CL-USER> (let* ((instance (make-instance 'foo :bar 42 :baz 69))
<syntaxhighlight lang="lisp">CL-USER> (let* ((instance (make-instance 'foo :bar 42 :baz 69))
(new-slots '((:name xenu :initargs (:xenu)))))
(new-slots '((:name xenu :initargs (:xenu)))))
(augment-instance-with-slots instance new-slots)
(augment-instance-with-slots instance new-slots)
Line 286: Line 286:


=={{header|D}}==
=={{header|D}}==
<syntaxhighlight lang=d>struct Dynamic(T) {
<syntaxhighlight lang="d">struct Dynamic(T) {
private T[string] vars;
private T[string] vars;


Line 321: Line 321:
Hello 11 ['x':2, 'y':4]</pre>
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:
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:
<syntaxhighlight lang=d>import std.stdio, std.variant, std.conv;
<syntaxhighlight lang="d">import std.stdio, std.variant, std.conv;


struct Dyn {
struct Dyn {
Line 341: Line 341:


ELENA 4.x:
ELENA 4.x:
<syntaxhighlight lang=elena>import extensions;
<syntaxhighlight lang="elena">import extensions;


class Extender : BaseExtender
class Extender : BaseExtender
Line 376: Line 376:
'''Array:'''
'''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.
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.
<syntaxhighlight lang=falcon>vect = [ 'alpha', 'beta', 'gamma' ]
<syntaxhighlight lang="falcon">vect = [ 'alpha', 'beta', 'gamma' ]
vect.dump = function ()
vect.dump = function ()
for n in [0: self.len()]
for n in [0: self.len()]
Line 385: Line 385:
vect.dump()</syntaxhighlight>
vect.dump()</syntaxhighlight>
Output from the above:
Output from the above:
<syntaxhighlight lang=falcon>0: alpha
<syntaxhighlight lang="falcon">0: alpha
1: beta
1: beta
2: gamma
2: gamma
Line 391: Line 391:
'''Dictionary:'''
'''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'.
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'.
<syntaxhighlight lang=falcon>function sub_func( value )
<syntaxhighlight lang="falcon">function sub_func( value )
self['prop'] -= value
self['prop'] -= value
return self.prop
return self.prop
Line 409: Line 409:
=={{header|FBSL}}==
=={{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.
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.
<syntaxhighlight lang=qbasic>#APPTYPE CONSOLE
<syntaxhighlight lang="qbasic">#APPTYPE CONSOLE


CLASS Growable
CLASS Growable
Line 451: Line 451:
Needs the FMS-SI (single inheritance) library code located here:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
http://soton.mpeforth.com/flag/fms/index.html
<syntaxhighlight lang=forth>include FMS-SI.f
<syntaxhighlight lang="forth">include FMS-SI.f
include FMS-SILib.f
include FMS-SILib.f


Line 485: Line 485:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<syntaxhighlight lang=freebasic>
<syntaxhighlight lang="freebasic">
' Class ... End Class
' Class ... End Class
' Esta característica aún no está implementada en el compilador.
' Esta característica aún no está implementada en el compilador.
Line 499: 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:
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:
<syntaxhighlight lang=go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 568: 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.
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.
<syntaxhighlight lang=groovy>class A {
<syntaxhighlight lang="groovy">class A {
final x = { it + 25 }
final x = { it + 25 }
private map = new HashMap()
private map = new HashMap()
Line 576: Line 576:


Test:
Test:
<syntaxhighlight lang=groovy>def a = new A()
<syntaxhighlight lang="groovy">def a = new A()
a.y = 55
a.y = 55
a.z = { println (new Date()); Thread.sleep 5000 }
a.z = { println (new Date()); Thread.sleep 5000 }
Line 595: Line 595:


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
{{omit from|Icon}}
Unicon implements object environments with records and supporting procedures for creation, initialization, and methods. To modify an instance you must create a new record then copy, amend, and replace it. Strictly speaking we can't guarantee the replace as there is no way to modify the existing object and we are creating a new instance with extensions. The procedures ''constructor'' and ''fieldnames'' are needed. This example doesn't do error checking. Here ''extend'' takes three arguments, the class instance, a list of new variable names as strings, and an optional list of new values to be assigned. The new instance is returned and the object is replaced by assignment. The caveat here is that if the object was assigned to anything else we will now have two objects floating around with possible side effects. As written this isn't safe from name collisions - aside from local declarations the use of a fixed constructor name uses the global name space. There is a final caveat that needs to be observed - if future implementations of objects change then this could easily stop working.
Unicon implements object environments with records and supporting procedures for creation, initialization, and methods. To modify an instance you must create a new record then copy, amend, and replace it. Strictly speaking we can't guarantee the replace as there is no way to modify the existing object and we are creating a new instance with extensions. The procedures ''constructor'' and ''fieldnames'' are needed. This example doesn't do error checking. Here ''extend'' takes three arguments, the class instance, a list of new variable names as strings, and an optional list of new values to be assigned. The new instance is returned and the object is replaced by assignment. The caveat here is that if the object was assigned to anything else we will now have two objects floating around with possible side effects. As written this isn't safe from name collisions - aside from local declarations the use of a fixed constructor name uses the global name space. There is a final caveat that needs to be observed - if future implementations of objects change then this could easily stop working.


''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).
''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).
<syntaxhighlight lang=unicon>
<syntaxhighlight lang="unicon">
link ximage
link ximage


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


<syntaxhighlight lang=io>Empty := Object clone
<syntaxhighlight lang="io">Empty := Object clone


e := Empty clone
e := Empty clone
Line 665: Line 664:
If you assign a value to the name which references a property of a class instance, that name within that instance gets that value.
If you assign a value to the name which references a property of a class instance, that name within that instance gets that value.


<syntaxhighlight lang=j> C=:<'exampleclass' NB. this will be our class name
<syntaxhighlight lang="j"> C=:<'exampleclass' NB. this will be our class name
V__C=: 0 NB. ensure the class exists
V__C=: 0 NB. ensure the class exists
OBJ1=:conew 'exampleclass' NB. create an instance of our class
OBJ1=:conew 'exampleclass' NB. create an instance of our class
Line 681: Line 680:
=={{header|JavaScript}}==
=={{header|JavaScript}}==
This kind of thing is fundamental to JavaScript, as it's a prototype-based language rather than a class-based one.
This kind of thing is fundamental to JavaScript, as it's a prototype-based language rather than a class-based one.
<syntaxhighlight lang=javascript>e = {} // generic object
<syntaxhighlight lang="javascript">e = {} // generic object
e.foo = 1
e.foo = 1
e["bar"] = 2 // name specified at runtime</syntaxhighlight>
e["bar"] = 2 // name specified at runtime</syntaxhighlight>
Line 688: Line 687:
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'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:
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:
<syntaxhighlight lang=jq>{"a":1} as $a | ($a + {"b":2}) as $a | $a
<syntaxhighlight lang="jq">{"a":1} as $a | ($a + {"b":2}) as $a | $a
</syntaxhighlight>Thus the value of $a has undergone the desired transition, that is, its final value is {"a":1, "b":2}.
</syntaxhighlight>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:<syntaxhighlight lang=jq>$a|.c = 3
A Javascript-like syntax can also be used to add (or update) a key, for example:<syntaxhighlight lang="jq">$a|.c = 3
# or equivalently:
# or equivalently:
$a|.["c"] = 3</syntaxhighlight>
$a|.["c"] = 3</syntaxhighlight>
Line 702: Line 701:
For example, consider the below JSON input data for a program processing phone numbers,
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:
where the type of phone numbers for the person is unknown until run-time:
<syntaxhighlight lang=xml>
<syntaxhighlight lang="xml">
{"phoneNumbers": [
{"phoneNumbers": [
{
{
Line 718: Line 717:
</syntaxhighlight>
</syntaxhighlight>
Add the data into a class member that is declared as a Dict structure:
Add the data into a class member that is declared as a Dict structure:
<syntaxhighlight lang=Julia>
<syntaxhighlight lang="julia">
mutable struct Contact
mutable struct Contact
name::String
name::String
Line 733: Line 732:
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:
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:


<syntaxhighlight lang=scala>// version 1.1.2
<syntaxhighlight lang="scala">// version 1.1.2


class SomeClass {
class SomeClass {
Line 783: Line 782:


Latitude is prototype-oriented, so adding slots at runtime is very straightforward and common.
Latitude is prototype-oriented, so adding slots at runtime is very straightforward and common.
<syntaxhighlight lang=Latitude>myObject := Object clone.
<syntaxhighlight lang="latitude">myObject := Object clone.


;; Name known at compile-time.
;; Name known at compile-time.
Line 792: Line 791:


=={{header|Lingo}}==
=={{header|Lingo}}==
<syntaxhighlight lang=Lingo>obj = script("MyClass").new()
<syntaxhighlight lang="lingo">obj = script("MyClass").new()


put obj.foo
put obj.foo
Line 807: Line 806:
The following example uses a prototype for simplicity.
The following example uses a prototype for simplicity.


<syntaxhighlight lang=logtalk>
<syntaxhighlight lang="logtalk">
% we start by defining an empty object
% we start by defining an empty object
:- object(foo).
:- object(foo).
Line 830: Line 829:
We can test our example by compiling and loading the two entities above and then querying the object:
We can test our example by compiling and loading the two entities above and then querying the object:


<syntaxhighlight lang=logtalk>
<syntaxhighlight lang="logtalk">
| ?- foo::bar(X).
| ?- foo::bar(X).
X = 1 ;
X = 1 ;
Line 840: Line 839:
=={{header|LOLCODE}}==
=={{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.
<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.
<syntaxhighlight lang=LOLCODE>HAI 1.3
<syntaxhighlight lang="lolcode">HAI 1.3


I HAS A object ITZ A BUKKIT
I HAS A object ITZ A BUKKIT
Line 870: Line 869:


=={{header|Lua}}==
=={{header|Lua}}==
<syntaxhighlight lang=lua>empty = {}
<syntaxhighlight lang="lua">empty = {}
empty.foo = 1</syntaxhighlight>
empty.foo = 1</syntaxhighlight>


Line 876: Line 875:
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.
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.


<syntaxhighlight lang=M2000 Interpreter>
<syntaxhighlight lang="m2000 interpreter">
Module checkit {
Module checkit {
class alfa {
class alfa {
Line 913: Line 912:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{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:
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:
<syntaxhighlight lang=Mathematica>
<syntaxhighlight lang="mathematica">
f[a]=1;
f[a]=1;
f[b]=2;
f[b]=2;
Line 928: Line 927:


If the name of the variable to add is known at compile time, then this is just standard class construction:
If the name of the variable to add is known at compile time, then this is just standard class construction:
<syntaxhighlight lang=MiniScript>empty = {}
<syntaxhighlight lang="miniscript">empty = {}
empty.foo = 1</syntaxhighlight>
empty.foo = 1</syntaxhighlight>


If the name of the variable to add is itself in a variable, then instead of dot syntax, use normal indexing:
If the name of the variable to add is itself in a variable, then instead of dot syntax, use normal indexing:


<syntaxhighlight lang=MiniScript>empty = {}
<syntaxhighlight lang="miniscript">empty = {}
varName = "foo"
varName = "foo"
empty[varName] = 1</syntaxhighlight>
empty[varName] = 1</syntaxhighlight>
Line 941: Line 940:
=={{header|Morfa}}==
=={{header|Morfa}}==
To emulate adding a variable to a class instance, Morfa uses user-defined operators <tt>`</tt> and <tt>&lt;-</tt>.
To emulate adding a variable to a class instance, Morfa uses user-defined operators <tt>`</tt> and <tt>&lt;-</tt>.
<syntaxhighlight lang=morfa>
<syntaxhighlight lang="morfa">
import morfa.base;
import morfa.base;


Line 1,011: Line 1,010:


=={{header|Nim}}==
=={{header|Nim}}==
<syntaxhighlight lang=nim>import json
<syntaxhighlight lang="nim">import json
{.experimental: "dotOperators".}
{.experimental: "dotOperators".}
template `.=`(js: JsonNode, field: untyped, value: untyped) =
template `.=`(js: JsonNode, field: untyped, value: untyped) =
Line 1,032: Line 1,031:
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.
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.


<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/runtime.h>


Line 1,054: Line 1,053:


You can also use a selector as the key, since two selectors with the same content are guaranteed to be equal:
You can also use a selector as the key, since two selectors with the same content are guaranteed to be equal:
<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/runtime.h>


Line 1,076: Line 1,075:
Octave is dynamically typed, and can have fields added in two methods:
Octave is dynamically typed, and can have fields added in two methods:


<syntaxhighlight lang=octave>
<syntaxhighlight lang="octave">
% Given struct "test"
% Given struct "test"
test.b=1;
test.b=1;
Line 1,086: Line 1,085:
===Unknown Method Access===
===Unknown Method Access===
This example traps unknown method calls, then sets or retrieves the values in an encapsulated directory object.
This example traps unknown method calls, then sets or retrieves the values in an encapsulated directory object.
<syntaxhighlight lang=ooRexx>
<syntaxhighlight lang="oorexx">
d = .dynamicvar~new
d = .dynamicvar~new
d~foo = 123
d~foo = 123
Line 1,129: Line 1,128:
===Dynamic Method Definitions===
===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.
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.
<syntaxhighlight lang=ooRexx>
<syntaxhighlight lang="oorexx">
d = .dynamicvar~new
d = .dynamicvar~new
d~foo = 123
d~foo = 123
Line 1,170: Line 1,169:
=={{header|OxygenBasic}}==
=={{header|OxygenBasic}}==
Simple implementation for making runtime members - supports integer, float and string types.
Simple implementation for making runtime members - supports integer, float and string types.
<syntaxhighlight lang=oxygenbasic>
<syntaxhighlight lang="oxygenbasic">
'=================
'=================
class fleximembers
class fleximembers
Line 1,249: Line 1,248:
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.
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.


<syntaxhighlight lang=oz>declare
<syntaxhighlight lang="oz">declare
%% Creates a new class derived from BaseClass
%% Creates a new class derived from BaseClass
%% with an added feature (==public immutable attribute)
%% with an added feature (==public immutable attribute)
Line 1,283: Line 1,282:
=={{header|Perl}}==
=={{header|Perl}}==
{{works with|Perl|5.x}}
{{works with|Perl|5.x}}
<syntaxhighlight lang=perl>package Empty;
<syntaxhighlight lang="perl">package Empty;


# Constructor. Object is hash.
# Constructor. Object is hash.
Line 1,301: Line 1,300:
Attempting to fetch/store "jelly" on a non-dynamic class would trigger a fatal error, unless said field had been explictly defined.
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+
Needs 0.8.1+
<!--<syntaxhighlight lang=Phix>-->
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">class</span> <span style="color: #000000;">wobbly</span> <span style="color: #000000;">dynamic</span>
<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>
<span style="color: #000080;font-style:italic;">-- (pre-define a few fields/methods if you like)</span>
Line 1,313: Line 1,312:


=={{header|PHP}}==
=={{header|PHP}}==
<syntaxhighlight lang=php>class E {};
<syntaxhighlight lang="php">class E {};


$e=new E();
$e=new E();
Line 1,326: Line 1,325:
In general, all instance variables in PicoLisp are dynamically created at
In general, all instance variables in PicoLisp are dynamically created at
runtime.
runtime.
<syntaxhighlight lang=PicoLisp>: (setq MyObject (new '(+MyClass))) # Create some object
<syntaxhighlight lang="picolisp">: (setq MyObject (new '(+MyClass))) # Create some object
-> $385605941
-> $385605941
: (put MyObject 'newvar '(some value)) # Set variable
: (put MyObject 'newvar '(some value)) # Set variable
Line 1,337: Line 1,336:
=={{header|Pike}}==
=={{header|Pike}}==
Pike does not allow adding variables to existing objects, but we can design a class that allows us to add variables.
Pike does not allow adding variables to existing objects, but we can design a class that allows us to add variables.
<syntaxhighlight lang=Pike>class CSV
<syntaxhighlight lang="pike">class CSV
{
{
mapping variables = ([]);
mapping variables = ([]);
Line 1,389: Line 1,388:
it using the 'pop11_compile' procedure.
it using the 'pop11_compile' procedure.


<syntaxhighlight lang=pop11>lib objectclass;
<syntaxhighlight lang="pop11">lib objectclass;


define :class foo;
define :class foo;
Line 1,420: Line 1,419:
=={{header|PowerShell}}==
=={{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:
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:
<syntaxhighlight lang=powershell>$x = 42 `
<syntaxhighlight lang="powershell">$x = 42 `
| Add-Member -PassThru `
| Add-Member -PassThru `
NoteProperty `
NoteProperty `
Line 1,449: Line 1,448:
=={{header|Python}}==
=={{header|Python}}==


<syntaxhighlight lang=python>class empty(object):
<syntaxhighlight lang="python">class empty(object):
pass
pass
e = empty()</syntaxhighlight>
e = empty()</syntaxhighlight>
Line 1,455: Line 1,454:
If the variable (attribute) name is known at "compile" time (hard-coded):
If the variable (attribute) name is known at "compile" time (hard-coded):


<syntaxhighlight lang=python> e.foo = 1</syntaxhighlight>
<syntaxhighlight lang="python"> e.foo = 1</syntaxhighlight>


If the variable name is determined at runtime:
If the variable name is determined at runtime:
<syntaxhighlight lang=python> setattr(e, name, value)</syntaxhighlight>
<syntaxhighlight lang="python"> setattr(e, name, value)</syntaxhighlight>


'''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.
'''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: Line 1,463:
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:
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:


<syntaxhighlight lang=python>class empty(object):
<syntaxhighlight lang="python">class empty(object):
def __init__(this):
def __init__(this):
this.foo = "whatever"
this.foo = "whatever"
Line 1,483: Line 1,482:
{{works with|Rakudo|2015.12}}
{{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.
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.
<syntaxhighlight lang=perl6>class Bar { } # an empty class
<syntaxhighlight lang="raku" line>class Bar { } # an empty class


my $object = Bar.new; # new instance
my $object = Bar.new; # new instance
Line 1,506: Line 1,505:
say $that.foo; # 5 - value from the cloned object</syntaxhighlight>
say $that.foo; # 5 - value from the cloned object</syntaxhighlight>
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.
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.
<syntaxhighlight lang=perl6>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }
<syntaxhighlight lang="raku" line>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }


say $lue; # 42
say $lue; # 42
Line 1,512: Line 1,511:
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:
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:


<syntaxhighlight lang=perl6>use MONKEY-TYPING;
<syntaxhighlight lang="raku" line>use MONKEY-TYPING;
augment class Int {
augment class Int {
method answer { "Life, the Universe, and Everything" }
method answer { "Life, the Universe, and Everything" }
Line 1,520: Line 1,519:


=={{header|REBOL}}==
=={{header|REBOL}}==
<syntaxhighlight lang=rebol>
<syntaxhighlight lang="rebol">
REBOL [
REBOL [
Title: "Add Variables to Class at Runtime"
Title: "Add Variables to Class at Runtime"
Line 1,572: Line 1,571:


=={{header|Red}}==
=={{header|Red}}==
<syntaxhighlight lang=Red>person: make object! [
<syntaxhighlight lang="red">person: make object! [
name: none
name: none
age: none
age: none
Line 1,586: Line 1,585:
=={{header|Ring}}==
=={{header|Ring}}==
We can add an attribute (or a group of attributes) to the object state using addattribute() function
We can add an attribute (or a group of attributes) to the object state using addattribute() function
<syntaxhighlight lang=ring>o1 = new point
<syntaxhighlight lang="ring">o1 = new point
addattribute(o1,"x")
addattribute(o1,"x")
addattribute(o1,"y")
addattribute(o1,"y")
Line 1,600: Line 1,599:


=={{header|Ruby}}==
=={{header|Ruby}}==
<syntaxhighlight lang=ruby>class Empty
<syntaxhighlight lang="ruby">class Empty
end
end


Line 1,616: Line 1,615:
"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.
"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:
Another way of adding a method to a singleton is:
<syntaxhighlight lang=ruby>yes_no = "Yes"
<syntaxhighlight lang="ruby">yes_no = "Yes"


def yes_no.not
def yes_no.not
Line 1,631: Line 1,630:
Since version 2.10 Scala supports dynamic types. Dynamic types have to implement trait ''Dynamic'' and implement methods ''selectDynamic'' and ''updateDynamic''.
Since version 2.10 Scala supports dynamic types. Dynamic types have to implement trait ''Dynamic'' and implement methods ''selectDynamic'' and ''updateDynamic''.


<syntaxhighlight lang=scala>import language.dynamics
<syntaxhighlight lang="scala">import language.dynamics
import scala.collection.mutable.HashMap
import scala.collection.mutable.HashMap


Line 1,646: Line 1,645:
Sample output in the REPL:
Sample output in the REPL:


<syntaxhighlight lang=scala>scala> val a = new A
<syntaxhighlight lang="scala">scala> val a = new A
a: A = A@7b20f29d
a: A = A@7b20f29d


Line 1,656: Line 1,655:


=={{header|Sidef}}==
=={{header|Sidef}}==
<syntaxhighlight lang=ruby>class Empty{};
<syntaxhighlight lang="ruby">class Empty{};
var e = Empty(); # create a new class instance
var e = Empty(); # create a new class instance
e{:foo} = 42; # add variable 'foo'
e{:foo} = 42; # add variable 'foo'
Line 1,663: Line 1,662:
=={{header|Slate}}==
=={{header|Slate}}==
Slate objects are prototypes:
Slate objects are prototypes:
<syntaxhighlight lang=slate>define: #Empty -> Cloneable clone.
<syntaxhighlight lang="slate">define: #Empty -> Cloneable clone.
define: #e -> Empty clone.
define: #e -> Empty clone.
e addSlotNamed: #foo valued: 1.</syntaxhighlight>
e addSlotNamed: #foo valued: 1.</syntaxhighlight>
Line 1,671: Line 1,670:
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 ;-)
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)
{{works with|Smalltalk/X}} (should work with all Smalltalks, though)
<syntaxhighlight lang=smalltalk>|addSlot p|
<syntaxhighlight lang="smalltalk">|addSlot p|


addSlot :=
addSlot :=
Line 1,688: Line 1,687:
].</syntaxhighlight>
].</syntaxhighlight>
create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
<syntaxhighlight lang=smalltalk>p := Point x:10 y:20.
<syntaxhighlight lang="smalltalk">p := Point x:10 y:20.
addSlot value:p value:'z'.
addSlot value:p value:'z'.
p z:30.
p z:30.
Line 1,696: Line 1,695:


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.
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.
<syntaxhighlight lang=smalltalk>!Object methodsFor:'adding slots'!
<syntaxhighlight lang="smalltalk">!Object methodsFor:'adding slots'!


addSlot: slotName
addSlot: slotName
Line 1,713: Line 1,712:
then, again create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
then, again create a 2D Point object, add a z slot, change and retrieve the z-value, finally inspect it (and see the slots).
<syntaxhighlight lang=smalltalk>p := Point x:10 y:20.
<syntaxhighlight lang="smalltalk">p := Point x:10 y:20.
p addSlot:'z'. "instance specific added slot"
p addSlot:'z'. "instance specific added slot"
p z:30.
p z:30.
Line 1,736: Line 1,735:
CG: commented the bad example; maybe the original author wants to fix it / comment on it.
CG: commented the bad example; maybe the original author wants to fix it / comment on it.


<syntaxhighlight lang=smalltalk>Object subclass: #Monkey
<syntaxhighlight lang="smalltalk">Object subclass: #Monkey
instanceVariableNames: 'aVar'
instanceVariableNames: 'aVar'
classVariableNames: ''
classVariableNames: ''
Line 1,810: Line 1,809:
We can use the same associated object mechanism as in Objective-C:
We can use the same associated object mechanism as in Objective-C:


<syntaxhighlight lang=swift>import Foundation
<syntaxhighlight lang="swift">import Foundation
let fooKey = UnsafeMutablePointer<UInt8>.alloc(1)
let fooKey = UnsafeMutablePointer<UInt8>.alloc(1)
Line 1,831: Line 1,830:


The code below uses the fact that each object is implemented as a namespace, to add a ''time'' variable to an instance of ''summation'':
The code below uses the fact that each object is implemented as a namespace, to add a ''time'' variable to an instance of ''summation'':
<syntaxhighlight lang=Tcl>% package require TclOO
<syntaxhighlight lang="tcl">% package require TclOO
% oo::class create summation {
% oo::class create summation {
constructor {} {
constructor {} {
Line 1,859: Line 1,858:
%</syntaxhighlight>
%</syntaxhighlight>
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.
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.
<syntaxhighlight lang=tcl>% oo::class create summation {
<syntaxhighlight lang="tcl">% oo::class create summation {
constructor {} {
constructor {} {
variable v 0
variable v 0
Line 1,890: Line 1,889:
=={{header|Wren}}==
=={{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.
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.
<syntaxhighlight lang=ecmascript>import "io" for Stdin, Stdout
<syntaxhighlight lang="ecmascript">import "io" for Stdin, Stdout


class Birds {
class Birds {
Line 1,940: Line 1,939:


=={{header|XBS}}==
=={{header|XBS}}==
<syntaxhighlight lang=xbs>set Object = {}
<syntaxhighlight lang="xbs">set Object = {}
Object.Hello = "World";
Object.Hello = "World";
log(Object.Hello);</syntaxhighlight>
log(Object.Hello);</syntaxhighlight>
Line 1,950: Line 1,949:
=={{header|zkl}}==
=={{header|zkl}}==
Once created, class structure is fixed. However, using reflection, you can blow apart the class structure, add what ever and recompile the class (at run time). The REPL does this to store intermediate user results (defined classes, functions, variables, etc). It is ugly, slow and left as an exercise to the reader who cares.
Once created, class structure is fixed. However, using reflection, you can blow apart the class structure, add what ever and recompile the class (at run time). The REPL does this to store intermediate user results (defined classes, functions, variables, etc). It is ugly, slow and left as an exercise to the reader who cares.
{{omit from|6502 Assembly}}
{{omit from|6502 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|Applesoft BASIC}}
{{omit from|68000 Assembly}}
{{omit from|ALGOL 68}}
{{omit from|ALGOL 68}}
{{omit from|Applesoft BASIC}}
{{omit from|ARM Assembly}}
{{omit from|ARM Assembly}}
{{omit from|AWK}}
{{omit from|AWK}}
{{omit from|Brainf***}}
{{omit from|Brainf***}}
{{omit from|C}}
{{omit from|C++}}
{{omit from|C++}}
{{omit from|Clojure}}
{{omit from|Clojure}}
{{omit from|C}}
{{omit from|Delphi}}
{{omit from|Delphi}}
{{omit from|Factor}}
{{omit from|F Sharp}}
{{omit from|F Sharp}}
{{omit from|Factor}}
{{omit from|Fortran}}
{{omit from|Fortran}}
{{omit from|Free Pascal}}
{{omit from|Free Pascal}}
Line 1,970: Line 1,969:
{{omit from|GUISS}}
{{omit from|GUISS}}
{{omit from|Haskell}}
{{omit from|Haskell}}
{{omit from|Icon}}
{{omit from|Integer BASIC}}
{{omit from|Integer BASIC}}
{{omit from|Java}}
{{omit from|Java}}
Line 1,988: Line 1,988:
{{omit from|Processing}}
{{omit from|Processing}}
{{omit from|PureBasic}}
{{omit from|PureBasic}}
{{omit from|R}}
{{omit from|Retro}}
{{omit from|Retro}}
{{omit from|Rust}}
{{omit from|Rust}}
{{omit from|R}}
{{omit from|Scheme}}
{{omit from|Scheme}}
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have objects. -->
{{omit from|TI-83 BASIC}}
{{omit from|TI-89 BASIC}} <!-- Does not have objects. -->
{{omit from|UNIX Shell}}
{{omit from|UNIX Shell}}
{{omit from|Z80 Assembly}}
{{omit from|Z80 Assembly}}