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

PascalABC.NET
(PascalABC.NET)
 
(97 intermediate revisions by 45 users not shown)
Line 1:
{{task|Object oriented}}
 
Demonstrate how to dynamically add variables to an object (a class instance) at runtime.
 
Line 6 ⟶ 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 15 ⟶ 16:
// ...
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="actionscript">var foo:Foo = new Foo();
foo.bar = "zap";</langsyntaxhighlight>
{{omit from|Modula-2}}
{{omit from|Scheme}}
 
=={{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 62 ⟶ 61:
Put_Line (EE.Boo & " with" & Integer'Image (EE.Foo));
end;
end Dynamic;</langsyntaxhighlight>
Sample output:
<pre>
I am Class with 1
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">define :myClass [name,surname][]
 
myInstance: to :myClass ["John" "Doe"]
print myInstance
 
myInstance\age: 35
print myInstance</syntaxhighlight>
 
{{out}}
 
<pre>[name:John surname:Doe]
[name:John surname:Doe age:35]</pre>
 
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<langsyntaxhighlight AutoHotkeylang="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:
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"CLASSLIB"
REM Create a base class with no members:
DIM class{method}
PROC_class(class{})
REM Instantiate the class:
PROC_new(myobject{}, class{})
REM Add a member at run-time:
member$ = "mymember#"
PROCaddmember(myobject{}, member$, 8)
REM Test that the member can be accessed:
PROCassign("myobject." + member$, "PI")
PRINT EVAL("myobject." + member$)
END
DEF PROCaddmember(RETURN obj{}, mem$, size%)
LOCAL D%, F%, P%
DIM D% DIM(obj{}) + size% - 1, F% LEN(mem$) + 8
P% = !^obj{} + 4
WHILE !P% : P% = !P% : ENDWHILE : !P% = F%
$$(F%+4) = mem$ : F%!(LEN(mem$) + 5) = DIM(obj{})
!(^obj{} + 4) = D%
ENDPROC
DEF PROCassign(v$, n$)
IF EVAL("FNassign(" + v$ + "," + n$ + ")")
ENDPROC
DEF FNassign(RETURN n, v) : n = v : = 0</syntaxhighlight>
 
=={{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 99 ⟶ 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 115 ⟶ 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}}
<syntaxhighlight lang="csharp">// ----------------------------------------------------------------------------------------------
//
// Program.cs - DynamicClassVariable
//
// Mikko Puonti, 2013
//
// ----------------------------------------------------------------------------------------------
 
using System;
using System.Dynamic;
 
namespace DynamicClassVariable
{
internal static class Program
{
#region Static Members
 
private static void Main()
{
// To enable late binding, we must use dynamic keyword
// ExpandoObject readily implements IDynamicMetaObjectProvider which allows us to do some dynamic magic
dynamic sampleObj = new ExpandoObject();
// Adding a new property
sampleObj.bar = 1;
Console.WriteLine( "sampleObj.bar = {0}", sampleObj.bar );
 
// We can also add dynamically methods and events to expando object
// More information: http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx
// This sample only show very small part of dynamic language features - there is lot's more
Console.WriteLine( "< Press any key >" );
Console.ReadKey();
}
 
#endregion
}
}</syntaxhighlight>
 
{{out}}
<pre>sampleObj.bar = 1
< Press any key ></pre>
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript"># CoffeeScript is dynamic, just like the Javascript it compiles to.
# You can dynamically add attributes to objects.
 
Line 136 ⟶ 230:
e.yo = -> "baz"
console.log e.foo, e.yo()
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 144 ⟶ 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 163 ⟶ 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 192 ⟶ 286:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">struct Dynamic(T) {
private T[string] vars;
 
Line 199 ⟶ 293:
}
 
@property void opDispatch(string key, U)(U value)/* pure*/ nothrow {
vars[key] = value;
}
Line 222 ⟶ 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 239 ⟶ 333:
d[attribute_name] = "something";
writeln(d[attribute_name]);
}</langsyntaxhighlight>
{{out}}
<pre>something</pre>
 
=={{header|Elena}}==
ELENA does not support adding a variablefield at run-time but it can be simulated with the help of a group objectmix-in.
<lang elena>#subject foo.
 
ELENA 6.x:
#class FieldContainer
<syntaxhighlight lang="elena">import extensions;
 
class Extender : BaseExtender
{
object foo : prop;
#field theValue.
constructor(object)
#method foo'set : anObject
[{
this theValueobject := anObject.object
]}
#method foo'get = theValue.
}
 
public program()
#symbol Program =>
{
[
#var anObjectobject := 234.;
// addingextending an object with a field
object := new Extender(object);
anObject := anObject~FieldContainer.
 
object.foo anObject:= set &foo:"bar".;
 
console.printLine(object,".foo=",object.foo);
'program'Output << anObject << ".foo=" << anObject foo.
 
].
console.readChar()
</lang>
}</syntaxhighlight>
{{out}}
<pre>
234.foo=bar
</pre>
 
=={{header|Falcon}}==
Line 277 ⟶ 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 284 ⟶ 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 306 ⟶ 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.
<syntaxhighlight lang="qbasic">#APPTYPE CONSOLE
 
CLASS Growable
PRIVATE:
DIM instructions AS STRING = "Sleep(1)"
:ExecCode
DIM dummy AS INTEGER = EXECLINE(instructions, 1)
PUBLIC:
METHOD Absorb(code AS STRING)
instructions = code
GOTO ExecCode
END METHOD
METHOD Yield() AS VARIANT
RETURN result
END METHOD
END CLASS
 
DIM Sponge AS NEW Growable()
 
Sponge.Absorb("DIM b AS VARIANT = 1234567890: DIM result AS VARIANT = b")
PRINT Sponge.Yield()
Sponge.Absorb("b = ""Hello world!"": result = b")
PRINT Sponge.Yield()
 
PAUSE</syntaxhighlight>
'''Output:'''
1234567890
Hello world!
Press any key to continue...
 
=={{header|Forth}}==
{{works with|Forth}}
Works with any ANS Forth
 
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<syntaxhighlight lang="forth">include FMS-SI.f
include FMS-SILib.f
 
 
 
\ We can add any number of variables at runtime by adding
\ objects of any type to an instance at run time. The added
\ objects are then accessible via an index number.
 
:class foo
object-list inst-objects \ a dynamically growable object container
:m init: inst-objects init: ;m
:m add: ( obj -- ) inst-objects add: ;m
:m at: ( idx -- obj ) inst-objects at: ;m
;class
 
foo foo1
 
: main
heap> string foo1 add:
heap> fvar foo1 add:
 
s" Now is the time " 0 foo1 at: !:
3.14159e 1 foo1 at: !:
 
0 foo1 at: p: \ send the print message to indexed object 0
1 foo1 at: p: \ send the print message to indexed object 1
;
 
main \ => Now is the time 3.14159
</syntaxhighlight>
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
' Class ... End Class
' Esta característica aún no está implementada en el compilador.
</syntaxhighlight>
 
 
=={{header|Go}}==
{{trans|Kotlin}}
<br>
Firstly, Go doesn't have classes or class variables but does have structs (an analogous concept) which consist of fields.
 
Adding fields to a struct at runtime is not possible as Go is a statically typed, compiled language and therefore the names of all struct fields need to be known at compile time.
 
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
 
import (
"bufio"
"fmt"
"log"
"os"
)
 
type SomeStruct struct {
runtimeFields map[string]string
}
 
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
 
func main() {
ss := SomeStruct{make(map[string]string)}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Create two fields at runtime: ")
for i := 1; i <= 2; i++ {
fmt.Printf(" Field #%d:\n", i)
fmt.Print(" Enter name : ")
scanner.Scan()
name := scanner.Text()
fmt.Print(" Enter value : ")
scanner.Scan()
value := scanner.Text()
check(scanner.Err())
ss.runtimeFields[name] = value
fmt.Println()
}
for {
fmt.Print("Which field do you want to inspect ? ")
scanner.Scan()
name := scanner.Text()
check(scanner.Err())
value, ok := ss.runtimeFields[name]
if !ok {
fmt.Println("There is no field of that name, try again")
} else {
fmt.Printf("Its value is '%s'\n", value)
return
}
}
}</syntaxhighlight>
 
{{out}}
Sample input/output:
<pre>
Create two fields at runtime:
Field #1:
Enter name : a
Enter value : rosetta
 
Field #2:
Enter name : b
Enter value : 64
 
Which field do you want to inspect ? a
Its value is 'rosetta'
</pre>
 
=={{header|Groovy}}==
 
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 327 ⟶ 584:
(0..2).each(a.z)
 
println a.q</langsyntaxhighlight>
 
Output:
Line 336 ⟶ 593:
Wed Feb 23 21:33:50 CST 2011
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}}==
{{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.
 
''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 378 ⟶ 625:
x[newvars[i]] := newvals[i] # add new vars = values
return x
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 404 ⟶ 651:
R_tempconstructor_1.d := 9
R_tempconstructor_1.e := 7</pre>
 
=={{header|Io}}==
 
All "instance variables" (or slots in Io nomenclature) are created at runtime.
 
<syntaxhighlight lang="io">Empty := Object clone
 
e := Empty clone
e foo := 1</syntaxhighlight>
 
=={{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 420 ⟶ 676:
0
W__OBJ2 NB. our other instance does not
|value error</langsyntaxhighlight>
 
=={{header|Java}}==
Adding variables to an object at runtime is not possible in Java which is a statically typed language requiring the names of all class variables to be known at compile time.
 
However, we can make it appear as though variables are being added at runtime by using a Map or similar structure.
<syntaxhighlight lang="java">
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
 
public final class AddVariableToClassInstanceAtRuntime {
 
public static void main(String[] args) {
Demonstration demo = new Demonstration();
System.out.println("Create two variables at runtime: ");
Scanner scanner = new Scanner(System.in);
for ( int i = 1; i <= 2; i++ ) {
System.out.println(" Variable number " + i + ":");
System.out.print(" Enter name: ");
String name = scanner.nextLine();
System.out.print(" Enter value: ");
String value = scanner.nextLine();
demo.runtimeVariables.put(name, value);
System.out.println();
}
scanner.close();
System.out.println("Two new runtime variables appear to have been created.");
for ( Map.Entry<String, Object> entry : demo.runtimeVariables.entrySet() ) {
System.out.println("Variable " + entry.getKey() + " = " + entry.getValue());
}
}
 
}
 
final class Demonstration {
Map<String, Object> runtimeVariables = new HashMap<String, Object>();
}
</syntaxhighlight>
{{ out }}
<pre>
Create two variables at runtime:
Variable number 1:
Enter name: Test
Enter value: 42
 
Variable number 2:
Enter name: Item
Enter value: 3.14
 
Two new runtime variables appear to have been created.
Variable Item = 3.14
Variable Test = 42
</pre>
 
=={{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:
<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}.
 
A Javascript-like syntax can also be used to add (or update) a key, for example:<syntaxhighlight lang="jq">$a|.c = 3
# or equivalently:
$a|.["c"] = 3</syntaxhighlight>
 
=={{header|Julia}}==
Julia does not allow direct modification of the data member variables of a type,
though class methods (just Julia functions) can be added without difficulty.
For special situations, such as when parsing an input file, where new data type names
may be appropriate, this can be accommodated using a Dict as one of the class variables.
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:
<syntaxhighlight lang="xml">
{"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}]}
</syntaxhighlight>
Add the data into a class member that is declared as a Dict structure:
<syntaxhighlight lang="julia">
mutable struct Contact
name::String
phonenumber::Dict{Any,Any}
end
 
person = Contact("Jane Doe", Dict())
person.phonenumber["home"] = "212 555-1234"
</syntaxhighlight>
 
=={{header|Kotlin}}==
Adding variables to an object at runtime is not possible in Kotlin (at least in the version targeting the JVM) which is a statically typed language and therefore the names of all class variables need to be known at compile time.
 
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
 
class SomeClass {
val runtimeVariables = mutableMapOf<String, Any>()
}
 
fun main(args: Array<String>) {
val sc = SomeClass()
println("Create two variables at runtime: ")
for (i in 1..2) {
println(" Variable #$i:")
print(" Enter name : ")
val name = readLine()!!
print(" Enter value : ")
val value = readLine()!!
sc.runtimeVariables.put(name, value)
println()
}
while (true) {
print("Which variable do you want to inspect ? ")
val name = readLine()!!
val value = sc.runtimeVariables[name]
if (value == null) {
println("There is no variable of that name, try again")
} else {
println("Its value is '${sc.runtimeVariables[name]}'")
return
}
}
}</syntaxhighlight>
 
{{out}}
Sample input/output:
<pre>
Create two variables at runtime:
Variable #1:
Enter name : a
Enter value : rosetta
 
Variable #2:
Enter name : b
Enter value : 64
 
Which variable do you want to inspect ? a
Its value is 'rosetta'
</pre>
 
=={{header|Latitude}}==
 
Latitude is prototype-oriented, so adding slots at runtime is very straightforward and common.
<syntaxhighlight lang="latitude">myObject := Object clone.
 
;; Name known at compile-time.
myObject foo := "bar".
 
;; Name known at runtime.
myObject slot 'foo = "bar".</syntaxhighlight>
 
=={{header|Lingo}}==
<syntaxhighlight lang="lingo">obj = script("MyClass").new()
 
put obj.foo
-- "FOO"
 
-- add new property 'bar'
obj.setProp(#bar, "BAR")
put obj.bar
-- "BAR"</syntaxhighlight>
 
=={{header|Logtalk}}==
Logtalk supports "hot patching" (aka "monkey patching") using a category, which is a first-class entity and a fine grained units of code reuse that can be (virtally) imported by any number of objects but also used for "complementing" an existing object, adding new functionality or patching existing functionality. Complementing cateogries can be enable or disabled globally or on a per object basis.
 
The following example uses a prototype for simplicity.
 
<syntaxhighlight lang="logtalk">
% we start by defining an empty object
:- object(foo).
 
% ensure that complementing categories are allowed
:- set_logtalk_flag(complements, allow).
 
:- end_object.
 
% define a complementing category, adding a new predicate
:- category(bar,
complements(foo)).
 
:- public(bar/1).
bar(1).
bar(2).
bar(3).
 
:- end_category.
</syntaxhighlight>
 
We can test our example by compiling and loading the two entities above and then querying the object:
 
<syntaxhighlight lang="logtalk">
| ?- foo::bar(X).
X = 1 ;
X = 2 ;
X = 3
true
</syntaxhighlight>
 
=={{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.
<syntaxhighlight 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</syntaxhighlight>
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}}==
<langsyntaxhighlight lang="lua">empty = {}
empty.foo = 1</langsyntaxhighlight>
 
=={{header|MathematicaM2000 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.
 
<syntaxhighlight lang="m2000 interpreter">
Module checkit {
class alfa {
x=5
}
\\ a class is a global function which return a group
Dim a(5)=alfa()
Print a(3).x=5
For a(3) {
group anyname { y=10}
\\ merge anyname to this (a(3))
this=anyname
}
Print a(3).y=10
Print Valid(a(2).y)=false
\\ make a copy of a(3) to m
m=a(3)
m.y*=2
Print m.y=20, a(3).y=10
\\ make a pointer to a(3) in n
n->a(3)
Print n=>y=10
n=>y+=20
Print a(3).y=30
\\ now n points to a(2)
n->a(2)
Print Valid(n=>y)=false ' y not exist in a(2)
Print n is a(2) ' true
\\ we don't have types for groups
Print valid(@n as m)=false ' n haven't all members of m
Print valid(@m as n)=true ' m have all members of n
}
checkit
</syntaxhighlight>
 
=={{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:
<syntaxhighlight lang="mathematica">
<lang Mathematica>
f[a]=1;
f[b]=2;
f[a]=3;
? f</langsyntaxhighlight>
Output:
Global`f
Line 445 ⟶ 979:
 
Here, the two 'variables' can be seen under the single heading 'f'. And of course all of this is done at runtime.
 
=={{header|MiniScript}}==
 
If the name of the variable to add is known at compile time, then this is just standard class construction:
<syntaxhighlight lang="miniscript">empty = {}
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:
 
<syntaxhighlight lang="miniscript">empty = {}
varName = "foo"
empty[varName] = 1</syntaxhighlight>
 
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.
 
=={{header|Morfa}}==
To emulate adding a variable to a class instance, Morfa uses user-defined operators <tt>`</tt> and <tt>&lt;-</tt>.
<syntaxhighlight lang="morfa">
import morfa.base;
 
template <T>
public struct Dynamic
{
var data: Dict<text, T>;
}
 
// convenience to create new Dynamic instances
template <T>
public property dynamic(): Dynamic<T>
{
return Dynamic<T>(new Dict<text,T>());
}
 
// introduce replacement operator for . - a quoting ` operator
public operator ` { kind = infix, precedence = max, associativity = left, quoting = right }
template <T>
public func `(d: Dynamic<T>, name: text): DynamicElementAccess<T>
{
return DynamicElementAccess<T>(d, name);
}
 
// to allow implicit cast from the wrapped instance of T (on access)
template <T>
public func convert(dea: DynamicElementAccess<T>): T
{
return dea.holder.data[dea.name];
}
 
// cannot overload assignment - introduce special assignment operator
public operator <- { kind = infix, precedence = assign }
template <T>
public func <-(access: DynamicElementAccess<T>, newEl: T): void
{
access.holder.data[access.name] = newEl;
}
 
func main(): void
{
var test = dynamic<int>;
test`a <- 10;
test`b <- 20;
test`a <- 30;
println(test`a, test`b);
}
 
// private helper structure
template <T>
struct DynamicElementAccess
{
var holder: Dynamic<T>;
var name: text;
import morfa.io.format.Formatter;
public func format(formatt: text, formatter: Formatter): text
{
return getFormatFunction(holder.data[name])(formatt, formatter);
}
}
</syntaxhighlight>
{{out}}
<pre>
30 20
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import json
{.experimental: "dotOperators".}
template `.=`(js: JsonNode, field: untyped, value: untyped) =
js[astToStr(field)] = %value
template `.`(js: JsonNode, field: untyped): JsonNode = js[astToStr(field)]
var obj = newJObject()
obj.foo = "bar"
echo(obj.foo)
obj.key = 3
echo(obj.key)</syntaxhighlight>
{{out}}
<pre>
"bar"
3
</pre>
 
=={{header|Objective-C}}==
Line 451 ⟶ 1,087:
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>
 
static void *fooKey = &fooKey; // one way to define a unique key is a pointer variable that points to itself
char fooKey;
 
int main (int argc, const char *argv[]) {
@autoreleasepool {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
id e = [[NSObject alloc] init];
 
// set
objc_setAssociatedObject(e, &fooKey, [NSNumber numberWithInt:@1], OBJC_ASSOCIATION_RETAIN);
 
// get
NSNumber *associatedObject = objc_getAssociatedObject(e, &fooKey);
NSLog(@"associatedObject: %@", associatedObject);
 
[e release];}
[pool drain];
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>
 
int main (int argc, const char *argv[]) {
@autoreleasepool {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
id e = [[NSObject alloc] init];
 
// set
objc_setAssociatedObject(e, @selector(foo), [NSNumber numberWithInt:@1], OBJC_ASSOCIATION_RETAIN);
 
// get
NSNumber *associatedObject = objc_getAssociatedObject(e, @selector(foo));
NSLog(@"associatedObject: %@", associatedObject);
 
[e release];}
[pool drain];
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 507 ⟶ 1,141:
===Unknown Method Access===
This example traps unknown method calls, then sets or retrieves the values in an encapsulated directory object.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
d = .dynamicvar~new
d~foo = 123
Line 546 ⟶ 1,180:
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.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
d = .dynamicvar~new
d~foo = 123
Line 587 ⟶ 1,221:
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 663 ⟶ 1,297:
a.delete
 
</syntaxhighlight>
</lang>
 
=={{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.
Line 669 ⟶ 1,304:
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 697 ⟶ 1,332:
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].
 
=={{header|PerlPascal}}==
Works with FPC (tested with version 3.2.2).
{{works with|Perl|5.x}}
<lang perl>package Empty;
 
This could be done by playing around with the custom variants a bit.
# Constructor. Object is hash.
sub new { return bless {}, shift; }
 
Let's put the following code in a separate unit:
package main;
<syntaxhighlight lang="pascal">
unit MyObjDef;
{$mode objfpc}{$h+}{$interfaces com}
interface
 
function MyObjCreate: Variant;
# Object.
my $o = Empty->new;
 
implementation
# Set runtime variable (key => value).
uses
$o->{'foo'} = 1;</lang>
Variants, Generics.Collections;
 
var
MyObjType: TInvokeableVariantType;
 
type
=={{header|Perl 6}}==
IMyObj = interface
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.
procedure SetVar(const aName: string; const aValue: Variant);
<lang perl6>class Bar { } # an empty class
function GetVar(const aName: string): Variant;
end;
 
TMyObj = class(TInterfacedObject, IMyObj)
my $object = Bar.new; # new instance
strict private
FMap: specialize TDictionary<string, Variant>;
public
constructor Create;
destructor Destroy; override;
procedure SetVar(const aName: string; const aValue: Variant);
function GetVar(const aName: string): Variant;
end;
 
TMyData = packed record
role a_role { # role to add a variable: foo,
VType: TVarType;
has $.foo is rw = 2; # with an initial value of 2
Dummy1: array[0..5] of Byte;
}
Dummy2: Pointer;
FObj: IMyObj;
end;
 
TMyObjType = class(TInvokeableVariantType)
$object does a_role; # compose in the role
procedure Clear(var V: TVarData); override;
procedure Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean); override;
function GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean; override;
function SetProperty(var V: TVarData; const aName: string; const aData: TVarData): Boolean; override;
end;
 
function MyObjCreate: Variant;
say $object.foo; # prints: 2
begin
$object.foo = 5; # change the variable
VarClear(Result);
say $object.foo; # prints: 5
TMyData(Result).VType := MyObjType.VarType;
TMyData(Result).FObj := TMyObj.Create;
end;
 
constructor TMyObj.Create;
my $ohno = Bar.new; # new Bar object
begin
#say $ohno.foo; # runtime error, base Bar class doesn't have the variable foo
FMap := specialize TDictionary<string, Variant>.Create;
end;
 
destructor TMyObj.Destroy;
my $this = $object.new; # instantiate a new Bar derived from $object
begin
say $this.foo; # prints: 2 - original role value
FMap.Free;
inherited;
end;
 
procedure TMyObj.SetVar(const aName: string; const aValue: Variant);
my $that = $object.clone; # instantiate a new Bar derived from $object copying any variables
begin
say $that.foo; # 5 - value from the cloned object</lang>
FMap.AddOrSetValue(LowerCase(aName), aValue);
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.
end;
<lang perl6>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }
 
function TMyObj.GetVar(const aName: string): Variant;
say $lue; # 42
begin
say $lue.answer; # Life, the Universe, and Everything</lang>
if not FMap.TryGetValue(LowerCase(aName), Result) then Result := Null;
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:
end;
 
procedure TMyObjType.Clear(var V: TVarData);
<lang perl6>use MONKEY_TYPING;
begin
augment class Int {
TMyData(V).FObj := nil;
method answer { "Life, the Universe, and Everything" }
V.VType := varEmpty;
}
end;
say 42.answer; # Life, the Universe, and Everything</lang>
 
This practice, though allowed, is considered to be Evil Action at a Distance.
procedure TMyObjType.Copy(var aDst: TVarData; const aSrc: TVarData; const Indir: Boolean);
begin
VarClear(Variant(aDst));
TMyData(aDst) := TMyData(aSrc);
end;
 
function TMyObjType.GetProperty(var aDst: TVarData; const aData: TVarData; const aName: string): Boolean;
begin
Result := True;
Variant(aDst) := TMyData(aData).FObj.GetVar(aName);
end;
 
function TMyObjType.SetProperty(var V: TVarData; const aName: string; const aData: TVarData): Boolean;
begin
Result := True;
TMyData(V).FObj.SetVar(aName, Variant(aData));
end;
 
initialization
MyObjType := TMyObjType.Create;
finalization
MyObjType.Free;
end.
</syntaxhighlight>
 
And main program:
<syntaxhighlight lang="pascal">
program test;
{$mode objfpc}{$h+}
uses
MyObjDef;
 
var
MyObj: Variant;
 
begin
MyObj := MyObjCreate;
MyObj.Answer := 42;
MyObj.Foo := 'Bar';
MyObj.When := TDateTime(34121);
WriteLn(MyObj.Answer);
WriteLn(MyObj.Foo);
//check if variable names are case-insensitive, as it should be in Pascal
WriteLn(MyObj.wHen);
end.
</syntaxhighlight>
{{out}}
<pre>
42
Bar
01.06.1993
</pre>
 
=={{header|PascalABC.NET}}==
Adding variables to an object at runtime is not possible in PascalABC.NET because it is a statically typed language requiring the names of all class variables to be known at compile time.
 
However, we can make it appear as though variables are being added at runtime by using a Dictionary.
<syntaxhighlight lang="delphi">
type
MyClass = class
private
dict := new Dictionary<string,object>;
public
procedure Add(name: string; value: object) := dict[name] := value;
property Items[name: string]: object read dict[name]; default;
end;
 
begin
var obj := new MyClass;
obj.Add('Name','PascalABC.NET');
obj.Add('Age',16);
Println(obj['Name'],obj['Age']);
var obj1 := new MyClass;
obj1.Add('X',2.3);
obj1.Add('Y',3.8);
Println(obj1['X'],obj1['Y']);
end.
</syntaxhighlight>
{{ out }}
<pre>
PascalABC.NET 16
2.3 3.8
</pre>
 
 
=={{header|Perl}}==
{{works with|Perl|5.x}}
<syntaxhighlight lang="perl">package Empty;
 
# Constructor. Object is hash.
sub new { return bless {}, shift; }
 
package main;
 
# Object.
my $o = Empty->new;
 
# Set runtime variable (key => value).
$o->{'foo'} = 1;</syntaxhighlight>
 
=={{header|Phix}}==
{{libheader|Phix/Class}}
Dynamic classes are really just wrappers to per-instance dictionaries, not entirely unlike Go/Kotlin/etc, but with slightly nicer syntax.<br>
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+
<!--<syntaxhighlight 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>
<span style="color: #008080;">end</span> <span style="color: #008080;">class</span>
<span style="color: #000000;">wobbly</span> <span style="color: #000000;">wobble</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new<span style="color: #0000FF;">(<span style="color: #0000FF;">)</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;">-- 0
--?wobble["jelly"] -- for dynamic names use []</span>
<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"
<!--</syntaxhighlight>-->
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">class E {};
 
$e=new E();
Line 764 ⟶ 1,545:
$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 PicoLisplang="picolisp">: (setq MyObject (new '(+MyClass))) # Create some object
-> $385605941
: (put MyObject 'newvar '(some value)) # Set variable
Line 776 ⟶ 1,557:
$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 Pikelang="pike">class CSV
{
mapping variables = ([]);
Line 811 ⟶ 1,592:
"greeting"
})
</syntaxhighlight>
</lang>
 
=={{header|Pop11}}==
Line 832 ⟶ 1,613:
it using the 'pop11_compile' procedure.
 
<langsyntaxhighlight lang="pop11">lib objectclass;
 
define :class foo;
Line 859 ⟶ 1,640:
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 892 ⟶ 1,673:
=={{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 907 ⟶ 1,688:
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 919 ⟶ 1,700:
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.
 
=={{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.
<syntaxhighlight lang="raku" line>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</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.
<syntaxhighlight lang="raku" line>my $lue = 42 but role { has $.answer = "Life, the Universe, and Everything" }
 
say $lue; # 42
say $lue.answer; # Life, the Universe, and Everything</syntaxhighlight>
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="raku" line>use MONKEY-TYPING;
augment class Int {
method answer { "Life, the Universe, and Everything" }
}
say 42.answer; # Life, the Universe, and Everything</syntaxhighlight>
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"
Author: oofoe
Date: 2009-12-04
URL: http://rosettacode.org/wiki/Adding_variables_to_a_class_instance_at_runtime
]
Line 974 ⟶ 1,793:
print [crlf "Fighter squadron:"]
foreach pilot squadron [probe pilot]
</syntaxhighlight>
</lang>
 
=={{header|Red}}==
<syntaxhighlight lang="red">person: make object! [
name: none
age: none
]
 
people: reduce [make person [name: "fred" age: 20] make person [name: "paul" age: 21]]
people/1: make people/1 [skill: "fishing"]
 
foreach person people [
print reduce [person/age "year old" person/name "is good at" any [select person 'skill "nothing"]]
]</syntaxhighlight>
 
=={{header|Ring}}==
We can add an attribute (or a group of attributes) to the object state using addattribute() function
<syntaxhighlight lang="ring">o1 = new point
addattribute(o1,"x")
addattribute(o1,"y")
addattribute(o1,"z")
see o1 {x=10 y=20 z=30}
class point</syntaxhighlight>
{{out}}
<pre>
x: 10.000000
y: 20.000000
z: 30.000000
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class Empty
end
 
Line 989 ⟶ 1,836:
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:
<syntaxhighlight lang="ruby">yes_no = "Yes"
 
def yes_no.not
replace( self=="Yes" ? "No": "Yes")
end
 
#Demo:
p yes_no.not # => "No"
p yes_no.not # => "Yes"
p "aaa".not # => undefined method `not' for "aaa":String (NoMethodError)</syntaxhighlight>
 
=={{header|Scala}}==
Line 997 ⟶ 1,855:
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,008 ⟶ 1,866:
map(name) = value
}
}</langsyntaxhighlight>
 
Sample output in the REPL:
 
<langsyntaxhighlight lang="scala">scala> val a = new A
a: A = A@7b20f29d
 
Line 1,019 ⟶ 1,877:
 
scala> a.foo
res10: Any = 42</langsyntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight 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'</syntaxhighlight>
 
=={{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}}==
the following addSlot function creates an anonymus class with the additional slot, defines accessor methods and clones a new instance from the given object which becomes the old one.
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)
<syntaxhighlight lang="smalltalk">|addSlot p|
 
addSlot :=
[:obj :slotName |
|anonCls newObj|
anonCls := obj class
subclass:(obj class name,'+') asSymbol
instanceVariableNames:slotName
classVariableNames:''
poolDictionaries:'' category:nil
inEnvironment:nil.
anonCls compile:('%1 ^ %1' bindWith:slotName).
anonCls compile:('%1:v %1 := v' bindWith:slotName).
newObj := anonCls cloneFrom:obj.
obj become:newObj.
].</syntaxhighlight>
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.
addSlot value:p value:'z'.
p z:30.
p z.
p z:40.
p inspect</syntaxhighlight>
 
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'!
 
addSlot: slotName
|anonCls newObj|
 
anonCls := self class
subclass:(self class name,'+') asSymbol
instanceVariableNames:slotName
classVariableNames:''
poolDictionaries:'' category:nil
inEnvironment:nil.
anonCls compile:('%1 ^ %1' bindWith:slotName).
anonCls compile:('%1:v %1 := v' bindWith:slotName).
newObj := anonCls cloneFrom:self.
self become:newObj.</syntaxhighlight>
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.
p addSlot:'z'. "instance specific added slot"
p z:30.
p z.
p z:40.
p inspect. "shows 3 slots"
"Point class is unaffected:"
p2 := Point x:20 y:30.
p2 z:40. -> error; Point does not implement z:
p2 inspect. "shows 2 slots"
"but we can create another instance of the enhanced point (even though its an anon class)"
p3 := p class new.
p3 x:1 y:2.
p3 z:4.
p3 inspect. "shows 3 slots"
</syntaxhighlight>
 
<!--
{{incorrect|Smalltalk|It extends the class (adds a new instance var and new method that will exists even in brand new future instances of that class), not only the particular instance. -- The description of the problem must be reworded then, as it
asks for adding variables to the class, not the instance.}}
 
<lang smalltalk>Object subclass: #Monkey
CG: commented the bad example; maybe the original author wants to fix it / comment on it.
 
<syntaxhighlight lang="smalltalk">Object subclass: #Monkey
instanceVariableNames: 'aVar'
classVariableNames: ''
Line 1,087 ⟶ 2,017:
aMonkey setX: 10 .
aMonkey inspect .
(aMonkey x) printNl .</langsyntaxhighlight>
 
Output is:
Line 1,099 ⟶ 2,029:
x: 10
10</pre>
-->
 
=={{header|Swift}}==
We can use the same associated object mechanism as in Objective-C:
 
<syntaxhighlight lang="swift">import Foundation
let fooKey = UnsafeMutablePointer<UInt8>.alloc(1)
class MyClass { }
let e = MyClass()
// set
objc_setAssociatedObject(e, fooKey, 1, .OBJC_ASSOCIATION_RETAIN)
// get
if let associatedObject = objc_getAssociatedObject(e, fooKey) {
print("associated object: \(associatedObject)")
} else {
print("no associated object")
}</syntaxhighlight>
 
=={{header|Tcl}}==
Line 1,104 ⟶ 2,055:
 
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 Tcllang="tcl">% package require TclOO
% oo::class create summation {
constructor {} {
Line 1,130 ⟶ 2,081:
% $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,159 ⟶ 2,110:
% # Show that it is only in one object...
% $s2 value time
can't read "time": no such variable</langsyntaxhighlight>
 
=={{header|Wren}}==
{{omit from|Applesoft BASIC}}
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="wren">import "io" for Stdin, Stdout
 
class Birds {
construct new(userFields) {
_userFields = userFields
}
userFields { _userFields }
}
 
var userFields = {}
System.print("Enter three fields to add to the Birds class:")
for (i in 0..2) {
System.write("\n name : ")
Stdout.flush()
var name = Stdin.readLine()
System.write(" value: ")
Stdout.flush()
var value = Num.fromString(Stdin.readLine())
userFields[name] = value
}
 
var birds = Birds.new(userFields)
 
System.print("\nYour fields are:\n")
for (kv in birds.userFields) {
System.print(" %(kv.key) = %(kv.value)")
}</syntaxhighlight>
 
{{out}}
Sample session:
<pre>
Enter three fields to add to the Birds class:
 
name : finch
value: 6
 
name : magpie
value: 7
 
name : wren
value: 8
 
Your fields are:
 
finch = 6
magpie = 7
wren = 8
</pre>
 
=={{header|XBS}}==
<syntaxhighlight lang="xbs">set Object = {}
Object.Hello = "World";
log(Object.Hello);</syntaxhighlight>
{{out}}
<pre>
World
</pre>
 
=={{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.
{{omit from|6502 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|ALGOL 68}}
{{omit from|Applesoft BASIC}}
{{omit from|ARM Assembly}}
{{omit from|AWK}}
{{omit from|Brainf***}}
{{omit from|C}}
{{omit from|C++}}
{{omit from|Clojure}}
{{omit from|C}}
{{omit from|Delphi}}
{{omit from|F Sharp}}
{{omit from|Factor}}
{{omit from|Fortran}}
{{omit from|Free Pascal}}
{{omit from|gnuplot}}
{{omit from|Go}}
{{omit from|GUISS}}
{{omit from|Haskell}}
{{omit from|Icon}}
{{omit from|Integer BASIC}}
{{omit from|Java}}
{{omit from|LaTeX}}
{{omit from|Lily}}
{{omit from|M4}}
{{omit from|Make}}
{{omit from|Maxima}}
{{omit from|ML/I}}
{{omit from|MakeModula-2}}
{{omit from|NetRexx}}
{{omit from|Object Pascal}}
{{omit from|OCaml}}
{{omit from|Octave}}
Line 1,185 ⟶ 2,211:
{{omit from|Pascal}}
{{omit from|PlainTeX}}
{{omit from|Processing}}
{{omit from|PureBasic}}
{{omit from|R}}
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have objects. -->
{{omit from|Retro}}
{{omit from|Rust}}
{{omit from|R}}
{{omit from|Scheme}}
{{omit from|TI-83 BASIC}}
{{omit from|TI-89 BASIC}} <!-- Does not have objects. -->
{{omit from|UNIX Shell}}
{{omit from|Z80 Assembly}}
{{omit from|ZX Spectrum Basic}} <!-- Does not have objects. -->
46

edits