Good point. This is not a template-specific problem; if you try to deserialize a derived class and the client doesn't know of that class... well there's not a lot one can do, unless you package the code of the methods with the object.

I think it's reasonable to limit (at least for now) things to requiring that the client knows about the exact type serialized. And they need to have a layout-compatible version. Which brings us to a related problem - versioning...


Andrei

On 08/08/2010 09:20 AM, Sean Kelly wrote:
Let me explain with an example:

interface Container {}
class SList(T) : Container {}

-- App A --

SList!(int) x;
x.serialize();

-- App B --

Container x = deserialize();

This will only work if App B has instantiated an SList!(int) somewhere, 
otherwise the TypeInfo won't exist.  This particular issue is only a problem in 
one part of std.concurrency: priority messages.  If the user does a 
receive(int), let's say, and there's a priority message waiting of type string 
it will be thrown as PriorityMessageException!(string).  If the priority 
message is a template...

Other than that, std.concurrency will work just fine with Orange as-is because 
receive() is a template so the type of the expected data is available at 
compile-time.

Regarding the issue above, what I'll probably end up doing is throwing a 
PriorityMessageException!(SerializedType) (where SerializedType is a lot like a 
Variant) and the user can call .deserialize!(string) or whatever if he wants to 
extract the data.  If someone has a better suggestion for how to handle this, 
I'd love to hear it.

On Aug 8, 2010, at 7:03 AM, Sean Kelly wrote:

I agree, but templates will always be a problem.

Sent from my iPhone

On Aug 8, 2010, at 6:48 AM, Jacob<[email protected]>  wrote:


On 8 aug 2010, at 14:26, Michel Fortin wrote:

Le 2010-08-08 à 1:47, Andrei Alexandrescu a écrit :

I think that would be great. Knowing nothing about Orange, I visited the 
website and read the feature lists and the tutorial (the reference seems to be 
missing for now). The latter contains:

auto a2 = serializer.deserialize!(A)(data);

which seems to require compile-time knowledge of the deserialized type. I'd 
expect the library to support something like

Object a2 = serializer.deserialize!Object(data);

and fill the object with an A. I'm pretty certain you've done that, it would be 
great to feature that within the tutorials and documentation. I'd also expect 
Variant to play a role there, e.g. you deserialize something and you get a 
Variant.

My own unreleased, unfinished and in-need-of-a-refactoring serialization module 
does that... but unfortunately dynamically recreating the right type cannot be 
so straightforward in the current state of runtime reflection.

This post turned out longer that I expected, please stay with me.

Runtime reflection currently gives you access *only* to the default 
constructor, so this is what my module do internally when unserializing a class:

   ClassInfo c = findClass(classNameFromSerializationStream);
   Object o = c.create();
   (cast(Unserializable)o).unserialize(serialiationStream);

Since we can't access a constructor with a different signature, we can't 
unserialize directly from the constructor. This is rather a weak point as it 
forces all objects to have a default constructor. Another options is for the 
user to manually register his own constructor with the serialization system 
prior unserializing, but that's much less convenient.

Currently I don't call the constructor, just creating an instance of the class 
and sets its fields. I don't know how good or bad that actually is. Another 
option would be to use the __ctor and call one of the constructors (if it has 
multiple constructors) with the default values for the signature.

The unserialize member function called above must be explicitly added by the 
user (either manually or with a mixin) because the fields don't reflect at 
runtime and the actual class is unknown at compile-time. And the class needs to 
conform to an interface that contains that unserialize function so we can find 
it at runtime.

I think that is too much extra work. One of my goals was to be able to 
serialize third party types.

So before adding a serialization library, I would suggest we solve the 
runtime-reflection problem and find a standard way to attach various attributes 
to types and members. That could be done as a library, but ideally it'd have 
some help from the compiler which could put this stuff where it really belongs: 
ClassInfo. Currently, QtD has its own mixins for that, my D/Objective-C bridge 
has its own mixins and class registration system, my serialization module has 
its own, surely Orange has its own, I believe PyD has its own... this is going 
to be a mess pretty soon if it isn't already.

Once we have a proper standardized runtime-reflection and attribute system, 
then the serialization module can focus on serialization instead of 
implementing various hacks to add and get to the information it needs.

That is absolutely the best solution. I tried to do the best I could with the 
current compiler/runtime.

--
Michel Fortin
[email protected]
http://michelf.com/



_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to