Proposal: user defined attributes

Jacob Carlborg doob at me.com
Sun Mar 18 14:58:25 PDT 2012


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


More information about the Digitalmars-d mailing list