Chances of D getting proper runtime reflection?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Aug 22 13:26:06 PDT 2011


On 8/22/11 2:19 PM, Jacob Carlborg wrote:
> On 2011-08-22 21:08, Andrei Alexandrescu wrote:
>> On 8/21/11 6:03 PM, dsimcha wrote:
>>> On 8/21/2011 6:35 PM, Andrei Alexandrescu wrote:
>>>> On 8/21/11 1:19 PM, Jacob Carlborg wrote:
>>>>> On 2011-08-21 17:30, Robert Clipsham wrote:
>>>>>> On 21/08/2011 16:05, Jacob Carlborg wrote:
>>>>>>> This is for a serialization library where third party types need
>>>>>>> to be
>>>>>>> serializable. I don't like the idea of annotate everything that
>>>>>>> should
>>>>>>> be serializable.
>>>>>>
>>>>>> You don't need to annotate it:
>>>>>>
>>>>>> void serialize(T)(T something);
>>>>>>
>>>>>> You have access to all the CT reflection stuff, and can generate the
>>>>>> necessary runtime reflection with that.
>>>>>
>>>>> I already have a fully working serialization library. I'm hoping to
>>>>> make
>>>>> it better. The problem is when (de)serializing through a base class
>>>>> reference. Currently you need to register the subclass with the
>>>>> serializer. If T is Base and the actually runtime type is Sub it won't
>>>>> work.
>>>>
>>>> If we get to the point where adding one line of code inside or
>>>> (preferably) outside a type to make it serializable, that would be
>>>> great.
>>>>
>>>> Andrei
>>>
>>> I've been playing with Jacob's code and we're already at that point.
>>> Example (requires Jacob's Orange library to be installed):
>>>
>>> import std.stdio, orange.serialization._,
>>> orange.serialization.archives._,
>>> std.exception;
>>>
>>> class Base {
>>> string baseString;
>>> }
>>>
>>> class Derived : Base {
>>> string derivedString;
>>> }
>>>
>>> void main() {
>>> auto archiver = new XMLArchive!char();
>>> auto serializer = new Serializer(archiver);
>>> serializer.register!Derived();
>>>
>>> auto derived = new Derived;
>>> derived.baseString = "Base";
>>> derived.derivedString = "Derived";
>>>
>>> Base baseRef = derived;
>>> auto serialized = serializer.serialize(baseRef);
>>> auto baseRef2 = serializer.deserialize!(Base)(serialized);
>>>
>>> enforce(baseRef2.classinfo is Derived.classinfo);
>>> auto derived2 = cast(Derived) baseRef;
>>> writeln(derived2.baseString, ' ', derived2.derivedString);
>>> }
>>>
>>>
>>> The registration is not even necessary if you're serializing a class
>>> with a compile time type identical to its runtime type. Of course the
>>> situation gets a little more complicated when classes have references to
>>> other classes (you need to register everything that could be
>>> transitively reachable) but it's still pretty good.
>>
>> That's not how it should work. The line of code needs to be declarative,
>> not imperative. "I want this class to be serializable" as opposed to "I
>> want to serialize this class with this particular archiver".
>>
>> Andrei
>
> You mean you want something like this:
>
> class Derived : Base
> {
> mixin serializable;
> }
>
> Instead of:
>
> serializer.register!Derived();

Yes. Better yet:

class Derived : Base
{
     ...
}

mixin(serializable!Derived());

i.e. so you can add serialization to classes you can't edit.

> The only way I can think of how this could work is to store a global
> list of the serializable classes. Any other suggestion how this would
> work? Note that all this wouldn't be necessary if my original post was
> implemented.

A global structure sounds the way to go.


Andrei


More information about the Digitalmars-d mailing list