Add a variable to a class instance at runtime: Difference between revisions
Content added Content deleted
(Omit from Lily) |
(added Morfa) |
||
Line 691: | Line 691: | ||
Here, the two 'variables' can be seen under the single heading 'f'. And of course all of this is done at runtime. |
Here, the two 'variables' can be seen under the single heading 'f'. And of course all of this is done at runtime. |
||
=={{header|Morfa}}== |
|||
To emulate adding a variable to a class instance, Morfa uses user-defined operators <tt>`</tt> and <tt><-</tt>. |
|||
<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); |
|||
} |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
30 20 |
|||
</pre> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |