On 2012-03-18 20:26, Walter Bright wrote:

Something like Jacob's proposal for compile time attributes would be
useful here. My failure to understand is about runtime attributes.

If we'll get user defined attributes that is accessible via runtime reflection I'm sure people will find uses cases for it that are not possible with compile time reflection. But currently I don't see any use cases for attributes per instance.

If I'm thinking correctly this can be used for serializing. Say that you want to serialize an object through a base class reference. Currently you will need to register the subclass using some mechanism due to the limited runtime reflection in D. But if it would be possible to enumerate all fields in a class and also set and get the values of the fields using runtime reflection it wouldn't be necessary to register the subclass.

Ok, now to the user defined attribute:

@attribute class NonSerialized {} // This is what's called a "marker" in Java. It doesn't contain any information, the information is the type itself.

@attribute class SerializeAs
{
    string value;
}

class Base
{
    int x;
    @SerializeAs(foo) int y;
    @NonSerialized int c;
}

@NonSerialized class Sub : Base
{
    int z;
}

Base sub = new Sub;
serialize(sub);

In this example the user defined attribute "NonSerialized" indicates that the class shouldn't be serialized. When the serializer is serializing "sub" the compile time type will be "Base" therefore it would need to use runtime reflection to also serialize the fields added in the subclass "Sub". To check if the object should be serialized the serializer need to be able to access user defined attributes using runtime reflection. Something like:

auto classInfo = sub.classinfo;
writeln(classInfo); // Sub

if (classInfo.hasAttribute("NonSerialized"))
    // skip serialization

else
{
    foreach (field ; classInfo.fields)
        if (!field.hasAttribute("NonSerialized"))
        {
            auto value = filed.value;
            string name;

            if (attribute = filed.attributes["SerializeAs"])
                name = attribute.value;

            else
                name = filed.name;

            // serialize the field
        }
}

We do all this during runtime because we want to serialize through base class references. If the runtime type is the same as the compile time type we can do this at compile time.

--
/Jacob Carlborg

Reply via email to