digitalmars.D.learn - D RTTI?
- H. S. Teoh (27/27) Mar 05 2012 I know D doesn't really have RTTI yet, but I'm experimenting with
- Justin Whear (13/44) Mar 05 2012 The normal approach is to use a string mixin statement in each derived
- H. S. Teoh (11/60) Mar 05 2012 OK, it's a bit ugly I supopse, but I can live with that.
- Timon Gehr (2/60) Mar 05 2012 You can check typeof(this).
- H. S. Teoh (35/43) Mar 05 2012 [...]
- H. S. Teoh (6/40) Mar 05 2012 [...]
- Kenji Hara (46/56) Mar 05 2012 How about "wrapper template class"?
- Jacob Carlborg (7/31) Mar 05 2012 If you actually want serialization, and this was not just an example,
- H. S. Teoh (10/35) Mar 06 2012 [...]
- Jacob Carlborg (46/77) Mar 06 2012 Yes, but by default is serializes everything you give it. Orange
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? (P.S. D just took on brand new levels of cool when I realized I could do something like this. Imagine doing this with C++ templates... ugh! What a painful thought!) T -- Tech-savvy: euphemism for nerdy.
Mar 05 2012
On Mon, 05 Mar 2012 12:16:14 -0800, 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? (P.S. D just took on brand new levels of cool when I realized I could do something like this. Imagine doing this with C++ templates... ugh! What a painful thought!) TThe normal approach is to use a string mixin statement in each derived class: template Serializable() { enum Serializable = q{...your code here...}; } class B : A { mixin(Serializable); } Unfortunately, I don't believe there's any mechanism to order derived classes to automatically perform the mixin.
Mar 05 2012
On Mon, Mar 05, 2012 at 08:41:53PM +0000, Justin Whear wrote:On Mon, 05 Mar 2012 12:16:14 -0800, H. S. Teoh wrote:OK, it's a bit ugly I supopse, but I can live with that. Is there a way to tell whether or not a given class is a derived class or not? I'm using the Serializable template to insert serialize() into the class, and for derived classes I need to insert "override void serialize() ..." but for the base class I have to omit "override". How can I detect this in the template? Thanks! T -- No! I'm not in denial!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? (P.S. D just took on brand new levels of cool when I realized I could do something like this. Imagine doing this with C++ templates... ugh! What a painful thought!) TThe normal approach is to use a string mixin statement in each derived class: template Serializable() { enum Serializable = q{...your code here...}; } class B : A { mixin(Serializable); } Unfortunately, I don't believe there's any mechanism to order derived classes to automatically perform the mixin.
Mar 05 2012
On 03/05/2012 11:33 PM, H. S. Teoh wrote:On Mon, Mar 05, 2012 at 08:41:53PM +0000, Justin Whear wrote:You can check typeof(this).On Mon, 05 Mar 2012 12:16:14 -0800, H. S. Teoh wrote:OK, it's a bit ugly I supopse, but I can live with that. Is there a way to tell whether or not a given class is a derived class or not? I'm using the Serializable template to insert serialize() into the class, and for derived classes I need to insert "override void serialize() ..." but for the base class I have to omit "override". How can I detect this in the template? Thanks! TI 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? (P.S. D just took on brand new levels of cool when I realized I could do something like this. Imagine doing this with C++ templates... ugh! What a painful thought!) TThe normal approach is to use a string mixin statement in each derived class: template Serializable() { enum Serializable = q{...your code here...}; } class B : A { mixin(Serializable); } Unfortunately, I don't believe there's any mechanism to order derived classes to automatically perform the mixin.
Mar 05 2012
On Tue, Mar 06, 2012 at 12:03:48AM +0100, Timon Gehr wrote:On 03/05/2012 11:33 PM, H. S. Teoh wrote:[...][...]Is there a way to tell whether or not a given class is a derived class or not? I'm using the Serializable template to insert serialize() into the class, and for derived classes I need to insert "override void serialize() ..." but for the base class I have to omit "override". How can I detect this in the template?You can check typeof(this).Ahh, that's what I was looking for. Awesome!!! By combining typeof(this) with __traits(hasMember,...), I can actually insert missing methods into a class if they haven't been defined yet, or override existing methods if they are already defined in the base class: template Serializable() { enum Serializable = q{ static if (__traits(hasMember, typeof(this), "serializable")) { // Override existing method override void serialize(...); } else { // Insert missing method void serialize(...); } }; } class A { // This causes A to acquire serialize() mixin(Serializable!()); } class B : A { // This causes B to override serialize() mixin(Serializable!()); } D is too cool for words. T -- For every argument for something, there is always an equal and opposite argument against it. Debates don't give answers, only wounded or inflated egos.
Mar 05 2012
On Mon, Mar 05, 2012 at 03:26:01PM -0800, H. S. Teoh wrote: [...]template Serializable() { enum Serializable = q{ static if (__traits(hasMember, typeof(this), "serializable"))[...] Ugh, that last string should read "serialize".{ // Override existing method override void serialize(...); } else { // Insert missing method void serialize(...); } }; } class A { // This causes A to acquire serialize() mixin(Serializable!()); } class B : A { // This causes B to override serialize() mixin(Serializable!()); } D is too cool for words. T -- For every argument for something, there is always an equal and opposite argument against it. Debates don't give answers, only wounded or inflated egos.-- "How are you doing?" "Doing what?"
Mar 05 2012
On Monday, 5 March 2012 at 22:31:58 UTC, H. S. Teoh wrote:OK, it's a bit ugly I supopse, but I can live with that. Is there a way to tell whether or not a given class is a derived class or not? I'm using the Serializable template to insert serialize() into the class, and for derived classes I need to insert "override void serialize() ..." but for the base class I have to omit "override". How can I detect this in the template?How about "wrapper template class"? --------- import std.stdio; class Serialized(T) : T { // 2.059 new feature: class template constructor this(A...)(A args) { static if (is(typeof(super(args)))) super(args); } void serialize() { foreach (i, name; __traits(allMembers, T)) { mixin("alias "~name~" Member;"); static if (is(typeof(Member) == function)) {} // member function else static if (!is(typeof(Member))) {} // has no type is member template else static if (is(Member)) {} // nested type declaration else writefln("[%d] %s", i, name); // field!! } } } class A { private int value; } class B : A { private string key; this(string s){ key = s; } } void main() { auto a = new Serialized!A(); a.serialize(); writeln("----"); auto b = new Serialized!B("hello"); b.serialize(); } output: --------- [0] value ---- [0] key [2] value
Mar 05 2012
On 2012-03-05 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? (P.S. D just took on brand new levels of cool when I realized I could do something like this. Imagine doing this with C++ templates... ugh! What a painful thought!)If you actually want serialization, and this was not just an example, you can use Orange: https://github.com/jacob-carlborg/orange http://www.dsource.org/projects/orange/ -- /Jacob Carlborg
Mar 05 2012
On Tue, Mar 06, 2012 at 08:17:07AM +0100, Jacob Carlborg wrote:On 2012-03-05 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)); } }If you actually want serialization, and this was not just an example, you can use Orange: https://github.com/jacob-carlborg/orange http://www.dsource.org/projects/orange/[...] For my purposes, I will eventually need to serialize only a subset of an object's properties, and only for a certain class of objects. Does Orange support selective serializations? T -- Having a smoking section in a restaurant is like having a peeing section in a swimming pool. -- Edward Burr
Mar 06 2012
On 2012-03-06 19:17, H. S. Teoh wrote:On Tue, Mar 06, 2012 at 08:17:07AM +0100, Jacob Carlborg wrote:Yes, but by default is serializes everything you give it. Orange supports several ways of customizing the serialization. You can choose to not serialize specific fields or a whole class: class Foo { int a; int b; mixin NonSerialized!(b); // will not serialize "b" } class Foo { int a; int b; mixin NonSerialized; // will not serialize "Foo" at all } If you want to customize the serialization process in even more detail that's possible as well, by implementing the Serializable interface: class Foo : Serializable { int a; void toData (Serializer serializer, Serializer.Data key) { serializer.serialize(a, "b"); } void fromData (Serializer serializer, Serializer.Data key) { a = serializer.deserialize!(int)("b"); } } Actually, you don't need to implement the interface, it will use compile time introspection to check if the methods are available. Or the unintrusive approach: class Foo { int a; } auto dg = (Foo value, Serializer serializer, Serializer.Data key) { serializer.serialize(a, "b"); } Serializer.registerSerializer!(Foo)(dg); You can find the docs here: http://dl.dropbox.com/u/18386187/orange_docs/orange.serialization.Serializer.html In the docs, don't forget the "package" tab. -- /Jacob CarlborgOn 2012-03-05 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)); } }If you actually want serialization, and this was not just an example, you can use Orange: https://github.com/jacob-carlborg/orange http://www.dsource.org/projects/orange/[...] For my purposes, I will eventually need to serialize only a subset of an object's properties, and only for a certain class of objects. Does Orange support selective serializations?
Mar 06 2012