digitalmars.D.learn - object.factory with template classes for serializing subclasses
- timotheecour (19/19) Sep 09 2012 Is there a way to use Object.factory with template classes?
- Jacob Carlborg (5/24) Sep 09 2012 I don't understand how Object.factory could help with serializing. But
- timotheecour (32/35) Sep 10 2012 All that'd be needed would be to have Object.factory working with
- Chris Cain (27/29) Sep 10 2012 Unless someone else wants to correct me, I'm going to say
- Chris Cain (7/12) Sep 10 2012 Also, now that I think about it, why couldn't you do this? (it's
- timotheecour (6/12) Sep 10 2012 that won't work with my example:
- Chris Cain (5/18) Sep 10 2012 Ah, I see now.
- Jacob Carlborg (4/8) Sep 10 2012 Hence proper runtime reflection is needed. I see no way out of this.
Is there a way to use Object.factory with template classes? eg: ---- class A(T){ T x; } auto a=Object.factory("A!int"); ---- Right now this fails (returns null). Use case: If we had this, it would GREATLY simplify serialization (eg as in the orange library) by not having to manually register subclasses of a given class, eg: class B{} class C:B{int x;} B c=new C; right now with orange, we need to register class C before calling serialization. If something like Object.factory("A!int") worked, this step could be made automatic.
Sep 09 2012
On 2012-09-10 01:27, timotheecour wrote:Is there a way to use Object.factory with template classes? eg: ---- class A(T){ T x; } auto a=Object.factory("A!int"); ---- Right now this fails (returns null). Use case: If we had this, it would GREATLY simplify serialization (eg as in the orange library) by not having to manually register subclasses of a given class, eg: class B{} class C:B{int x;} B c=new C; right now with orange, we need to register class C before calling serialization. If something like Object.factory("A!int") worked, this step could be made automatic.I don't understand how Object.factory could help with serializing. But what would help is if we did get proper runtime reflection. -- /Jacob Carlborg
Sep 09 2012
I don't understand how Object.factory could help with serializing. But what would help is if we did get proper runtime reflection.All that'd be needed would be to have Object.factory working with templates, here's how: ---- unittest{ class A{} class B{int x;} A a=new B; auto c=serialize(a);//will serialize field "x", no need to register!B } auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); } class SerializerBase{//could also be an interface auto serialize(Object a){} } class Serializer(T):SerializerBase{ auto serialize(Object a){ auto b=cast(T)a; foreach (name; __traits(allMembers, T)) { //now we have access to fields of most derived type; //we can get the fields from base class as well. } } } ---- I've left out details to focus on the key part. Deserialization is very similar. So the question is: is that technically impossible or not to enhance Object.factory in such ways?
Sep 10 2012
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote:So the question is: is that technically impossible or not to enhance Object.factory in such ways?Unless someone else wants to correct me, I'm going to say technically impossible. Object.factory constructs a class at runtime given a string of the name of the class. Templates, however, are created at compile-time only. Basically, the compiler creates a new type every time it sees a template being used with new template arguments. So, as you can imagine, there doesn't exist any object for Object.factory to find at run time. Technically, code like this MIGHT be possible: --- import std.stdio; class MyB(T) { this() { writeln("hello MyB!(" ~ T.stringof ~")"); } } void main() { // create the actual type at compile-time Object b = Object.factory(MyB!int.classinfo.name); writeln("b = ", b); } --- In this case, the type (I'd think) is actually created at compile-time, so it actually exists so that Object.factory can get it. However, the code you showed in your previous post (just purely existing in the string) could never work.
Sep 10 2012
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote:auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); }Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); }
Sep 10 2012
Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); }that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x.
Sep 10 2012
On Tuesday, 11 September 2012 at 04:47:11 UTC, timotheecour wrote:Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code.Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); }that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x.
Sep 10 2012
On 2012-09-11 07:57, Chris Cain wrote:Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code.Hence proper runtime reflection is needed. I see no way out of this. -- /Jacob Carlborg
Sep 10 2012