Sorry to resurrect an old (4 days) thread.<br>I modified the example a bit, getting rid of '...' in DynMethod and modifying opDispatch as Stanislav suggested. It works, and it's fun to play with:<br><br>module dynamicmethods;<br>
<br>import std.stdio;<br>import std.conv;<br>import std.variant;<br><br>alias Variant delegate(Dynamic self, Variant[] args) DynMethod;<br><br>class Dynamic {<br> private DynMethod[string] methods;<br> void addMethod(string name, DynMethod m) {<br>
methods[name] = m;<br> }<br> void removeMethod(string name) {<br> methods.remove(name);<br> }<br> // Dispatch dynamically on method<br> Variant call(string methodName, Variant[] args) {<br>
return methods[methodName](this, args);<br> }<br> // Provide syntactic sugar with opDispatch<br> Variant opDispatch(string m, Args...)(Args args) {<br> Variant[] packedArgs = new Variant[args.length];<br>
foreach (i, arg; args) {<br> packedArgs[i] = Variant(arg);<br> }<br> return call(m, packedArgs);<br> }<br>}<br><br>void main() {<br> auto obj = new Dynamic;<br>
obj.addMethod("sayHello",<br> (Dynamic, Variant[]) {<br> writeln("Hello, world!");<br> return Variant();<br> });<br> // m is just the previous anonymous delegate.<br>
DynMethod m = (Dynamic, Variant[]) {<br> writeln("Hello, world!");<br> return Variant();<br> };<br> obj.sayHello(); // Prints "Hello, world!"<br>
// Now, what about a meta-method? test adds a bunch of methods in one go:<br> obj.addMethod("test",<br> (Dynamic self, Variant[] args) {<br> writeln("the dynamic class currently has ", self.methods.length, " methods: ", self.methods.keys);<br>
foreach(i,arg; args) self.addMethod("method"~to!string(i), arg.get!DynMethod);<br> writeln("Now, the dynamic class has ", self.methods.length, " methods: ", self.methods.keys);<br>
return Variant();<br> });<br> obj.test(m); // adds m to obj, as method0<br> obj.method0(); // tests it. It prints "Hello, world!"<br>}<br><br>