Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 20, 2010 Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
I've typed this example program in, but it doesn't compile. I looked up the The D programming language errata but it wasn't listed. I'm using DMD v2.048. >> /** Date: Aug 20, 2010 This was copied from TDPL book pages 386 - 387 */ module dynamicmethods; import std.stdio; import std.variant; alias Variant delegate(Dynamic self, Variant[] args...) DynMethod; class Dynamic { private DynMethod[string] methods; void addMethod(string name, DynMethod m) { methods[name] = m; } void removeMethod(string name) { methods.remove(name); } // Dispatch dynamically on method Variant call(string methodName, Variant[] args...) { return methods[methodName](this, args); } // Provide syntactic sugar with opDispatch Variant opDispatch(string m, Args)(Args args...) { Variant[] packedArgs = new Variant[args.length]; foreach (i, arg; args) { packedArgs[i] = Variant(arg); } return call(m, args); } } void main() { auto obj = new Dynamic; obj.addMethod("sayHello", Variant(Dynamic, Variant[]) { //#error here. (found '{' expecting ',' writeln("Hello, world!"); return Variant(); }); obj.sayHello(); // Prints "Hello, world!" } << |
August 20, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | 20.08.2010 13:00, Joel Christensen wrote:
There seem to be quite a few errors in this one:
> /**
> Date: Aug 20, 2010
> This was copied from TDPL book pages 386 - 387
> */
> module dynamicmethods;
>
> import std.stdio;
> import std.variant;
>
> alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
>
> class Dynamic {
> private DynMethod[string] methods;
> void addMethod(string name, DynMethod m) {
> methods[name] = m;
> }
> void removeMethod(string name) {
> methods.remove(name);
> }
> // Dispatch dynamically on method
> Variant call(string methodName, Variant[] args...) {
> return methods[methodName](this, args);
> }
> // Provide syntactic sugar with opDispatch
> Variant opDispatch(string m, /*was: Args*/Args...)(/*was: Args args...*/Args args) { // There should've been variadic template instead of variadic function
> Variant[] packedArgs = new Variant[args.length];
> foreach (i, arg; args) {
> packedArgs[i] = Variant(arg);
> }
> return call(m, /*was: args*/packedArgs); // args was used instead of packedArgs
> }
> }
>
> void main() {
> auto obj = new Dynamic;
> obj.addMethod("sayHello",
> delegate Variant(Dynamic, Variant[]...) { // delegate keyword was missing, and it wasn't matching DynMethod signature
> writeln("Hello, world!");
> return Variant();
> });
> obj.sayHello(); // Prints "Hello, world!"
> }
Maybe Andrej can add this one to errata too? :)
|
August 20, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | You mean Andrei?
P.S. anyone can edit the errata page. It has a history backup, so if someone accidentally screws up something you can roll back to a previous version. If you find something that needs to be added, go ahead and do it.
Btw., I haven't reached that page yet. :p
Stanislav Blinov Wrote:
> 20.08.2010 13:00, Joel Christensen wrote:
>
> There seem to be quite a few errors in this one:
>
> > /**
> > Date: Aug 20, 2010
> > This was copied from TDPL book pages 386 - 387
> > */
> > module dynamicmethods;
> >
> > import std.stdio;
> > import std.variant;
> >
> > alias Variant delegate(Dynamic self, Variant[] args...) DynMethod;
> >
> > class Dynamic {
> > private DynMethod[string] methods;
> > void addMethod(string name, DynMethod m) {
> > methods[name] = m;
> > }
> > void removeMethod(string name) {
> > methods.remove(name);
> > }
> > // Dispatch dynamically on method
> > Variant call(string methodName, Variant[] args...) {
> > return methods[methodName](this, args);
> > }
> > // Provide syntactic sugar with opDispatch
> > Variant opDispatch(string m, /*was: Args*/Args...)(/*was: Args
> > args...*/Args args) { // There should've been variadic template
> > instead of variadic function
> > Variant[] packedArgs = new Variant[args.length];
> > foreach (i, arg; args) {
> > packedArgs[i] = Variant(arg);
> > }
> > return call(m, /*was: args*/packedArgs); // args was used
> > instead of packedArgs
> > }
> > }
> >
> > void main() {
> > auto obj = new Dynamic;
> > obj.addMethod("sayHello",
> > delegate Variant(Dynamic, Variant[]...) { // delegate keyword
> > was missing, and it wasn't matching DynMethod signature
> > writeln("Hello, world!");
> > return Variant();
> > });
> > obj.sayHello(); // Prints "Hello, world!"
> > }
> Maybe Andrej can add this one to errata too? :)
|
August 20, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 20.08.2010 15:49, Andrej Mitrovic wrote: > You mean Andrei? Nope :p > P.S. anyone can edit the errata page. It has a history backup, so if someone accidentally screws up something you can roll back to a previous version. If you find something that needs to be added, go ahead and do it. > Yeah, I know that. It's just that I can't do it till tomorrow, because I don't have Internet at work except for mail :| > Btw., I haven't reached that page yet. :p > |
August 24, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Attachments:
| Sorry to resurrect an old (4 days) thread. 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: module dynamicmethods; import std.stdio; import std.conv; import std.variant; alias Variant delegate(Dynamic self, Variant[] args) DynMethod; class Dynamic { private DynMethod[string] methods; void addMethod(string name, DynMethod m) { methods[name] = m; } void removeMethod(string name) { methods.remove(name); } // Dispatch dynamically on method Variant call(string methodName, Variant[] args) { return methods[methodName](this, args); } // Provide syntactic sugar with opDispatch Variant opDispatch(string m, Args...)(Args args) { Variant[] packedArgs = new Variant[args.length]; foreach (i, arg; args) { packedArgs[i] = Variant(arg); } return call(m, packedArgs); } } void main() { auto obj = new Dynamic; obj.addMethod("sayHello", (Dynamic, Variant[]) { writeln("Hello, world!"); return Variant(); }); // m is just the previous anonymous delegate. DynMethod m = (Dynamic, Variant[]) { writeln("Hello, world!"); return Variant(); }; obj.sayHello(); // Prints "Hello, world!" // Now, what about a meta-method? test adds a bunch of methods in one go: obj.addMethod("test", (Dynamic self, Variant[] args) { writeln("the dynamic class currently has ", self.methods.length, " methods: ", self.methods.keys); foreach(i,arg; args) self.addMethod("method"~to!string(i), arg.get!DynMethod); writeln("Now, the dynamic class has ", self.methods.length, " methods: ", self.methods.keys); return Variant(); }); obj.test(m); // adds m to obj, as method0 obj.method0(); // tests it. It prints "Hello, world!" } |
August 31, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | Thanks for the fix up Philippe. Just a little note. Where it says 'DynMethod m', you can put 'auto m', but I'm wondering is it some times clearer to have the class name even though 'auto' works. |
September 01, 2010 Re: Dynamic method example in TDPL | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen Attachments:
| On Wed, Sep 1, 2010 at 01:24, Joel Christensen <joelcnz@gmail.com> wrote:
> Thanks for the fix up Philippe.
>
> Just a little note. Where it says 'DynMethod m', you can put 'auto m', but I'm wondering is it some times clearer to have the class name even though 'auto' works.
>
It depends on what you prefer. auto adds flexibility: if you use auto a lot, you can change the 'typed' parts of your code and the parts with auto will likely stay the same, propagating the change without hiccup, which is well and good. But you also loose sight of what the 'current' type is. The compiler knows it perfectly well, though, and you can count on static typing to help you when it can.
Personally, I'm a bit leery of using auto in complex, recursive, templated code: not so long ago, auto regularly created nasty forward declaration errors. I think some were squashed recently, but I'm still testing the water here.
|
Copyright © 1999-2021 by the D Language Foundation