Add a variable to a class instance at runtime: Difference between revisions
Content deleted Content added
Rewritten D entries |
|||
Line 191: | Line 191: | ||
=={{header|D}}== |
=={{header|D}}== |
||
⚫ | |||
D is a statically compiled language, so there are some limits. |
|||
private T[string] vars; |
|||
This adds a new 'attribute' to a struct/class instance, of type T: |
|||
⚫ | |||
import std.traits: isImplicitlyConvertible; |
|||
@property T opDispatch(string key)() pure nothrow { |
|||
⚫ | |||
return vars[key]; |
|||
⚫ | |||
@property void opDispatch(string key, U)(U value)/*pure*/ nothrow { |
|||
vars[key] = value; |
|||
T opDispatch(Types...)(Types args) |
|||
⚫ | |||
if (!args.length || (args.length == 1 && isImplicitlyConvertible!(Types[0],T))) { |
|||
static if (args.length) { |
|||
data[name] = args[0]; |
|||
return args[0]; |
|||
} else |
|||
return data[name]; |
|||
⚫ | |||
⚫ | |||
} |
} |
||
void main() { |
void main() { |
||
import std.variant, std.stdio; |
|||
S!long s; |
|||
⚫ | |||
// If the type of the attributes is known at compile-time: |
|||
writeln(s.foo()); |
|||
auto d1 = Dynamic!double(); |
|||
d1.first = 10.5; |
|||
d1.second = 20.2; |
|||
writeln(d1.first, " ", d1.second); |
|||
// If the type of the attributes is mixed: |
|||
auto d2 = Dynamic!Variant(); |
|||
d2.a = "Hello"; |
|||
⚫ | |||
d2.c = ['x':2, 'y':4]; |
|||
writeln(d2.a, " ", d2.b, " ", d2.c); |
|||
immutable int x = d2.b.get!int; |
|||
}</lang> |
}</lang> |
||
{{out}} |
|||
⚫ | |||
<pre>10.5 20.2 |
|||
<lang d>import std.stdio: writeln; |
|||
Hello 11 ['x':2, 'y':4]</pre> |
|||
⚫ | |||
⚫ | |||
struct |
struct Dyn { |
||
Variant[string] data; |
|||
alias data this; |
alias data this; |
||
} |
} |
||
void main() { |
void main(string[] args) { |
||
Dyn d; |
|||
const attribute_name = text("attribute_", args.length); |
|||
string name = "bar"; |
|||
d[attribute_name] = "something"; |
|||
writeln( |
writeln(d[attribute_name]); |
||
}</lang> |
}</lang> |
||
{{out}} |
|||
If the type is variable it can be used an associative array of variants, but things become more complex. Adding a name to all instances of a class can be possible. |
|||
<pre>something</pre> |
|||
=={{header|Elena}}== |
=={{header|Elena}}== |