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>&lt;-</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}}==