D RTTI?

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Mar 5 17:15:02 PST 2012


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


More information about the Digitalmars-d-learn mailing list