Chances of D getting proper runtime reflection?

Jacob Carlborg doob at me.com
Mon Aug 22 23:39:36 PDT 2011


On 2011-08-22 22:00, Timon Gehr wrote:
> On 08/22/2011 09: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();
>>
>> 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.
>>
>
> I think that you maybe register too late in the process?
>
>  > auto archiver = new XMLArchive!char();
>  > auto serializer = new Serializer(archiver);
>  > serializer.register!Derived();
>
> If it works that way, you have to register every class anew if you want
> to serialize it with another archiver, right?

Yes, that's how it currently works. I can make the "register" method 
static instead.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list