On Tue, Mar 06, 2012 at 01:51:51AM +0100, Artur Skawina wrote: > On 03/05/12 21:16, H. S. Teoh wrote: > > I know D doesn't really have RTTI yet, but I'm experimenting with > > "faking" it by doing something like: > > > > class A { > > string prop1; > > int prop2; > > ... > > void serialize() { > > __serialize(this); > > } > > } > > > > void __serialize(T)(T obj) { > > writeln(typeid(obj)); > > foreach (name; __traits(derivedMembers, T)) { > > writefln("%s = %s", name, > > __traits(getMember,obj,name)); > > } > > } > > > > The only thing is, serialize() has to be declared in every derived > > class, because T needs to be known at compile-time. Is there a way to > > "automate" this? I.e., automatically insert the serialize() boilerplate > > code into derived classes? > > Well, what exactly are you trying to do? IOW why "derivedMembers" - do > you really need to skip serializing parts of the class hierarchy?
That was a mistake. It's supposed to be allMembers, not derivedMembers. :-) > If not, this should work. > > class A { > string prop1; > int prop2; > > void serialize(this THIS)() { > __serialize(cast(THIS*)&this); > } > } > > void __serialize(T)(T* obj) { > writef("%s {\n", typeid(*obj)); > foreach (name; __traits(allMembers, T)) { > static if (__traits(compiles,&__traits(getMember,obj,name))) { > alias typeof(__traits(getMember,obj,name)) MT; > static if (is(MT==function)) > continue; > else { > auto m = __traits(getMember,obj,name); > if (is(MT:const(char[]))) > writef(" %s %s = \"%s\";\n", typeid(MT), name, m); > else > writef(" %s %s = %s;\n", typeid(MT), name, m); > } > } > } > writef("}\n"); > } > > And it will do the right thing for derived classes too. > > Real programmers don't use mixins, :^) [...] Whoa! Now this is cool stuff. Exactly what I was looking for. :-) What exactly does "this THIS" do? Bind to the most derived type? I didn't know you could do that. Plus, I was also struggling with skipping function members... it's actually so easy! Am I the only one who has trouble remembering exactly what the various forms of is(...) are used for?? My brain still has trouble coming up with a consistent interpretation of is(...). It seems like a bunch of random stuff thrown into the same syntax. (OK, perhaps not random, but I don't see any unifying rationale to its various forms.) T -- A mathematician is a device for turning coffee into theorems. -- P. Erdos