www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - UDA syntax

reply "Joseph Cassman" <jc7919 outlook.com> writes:
I was wondering what the syntax is for user defined attributes 
(i.e. bug 9222) implemented in release 2.061. I was still unclear 
after reading the thread 
forum.dlang.org/thread/k7afq6$2832$1 digitalmars.com.

Thanks for the help

Joseph
Jan 16 2013
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/16/2013 05:59 PM, Joseph Cassman wrote:
 I was wondering what the syntax is for user defined attributes (i.e. bug
 9222) implemented in release 2.061. I was still unclear after reading
 the thread forum.dlang.org/thread/k7afq6$2832$1 digitalmars.com.

 Thanks for the help

 Joseph
The following is the code that I had used for experimenting with UDAs: import std.stdio; /* Here we define a type which we will later use to add attributes * to. Although this type can have member variables as well, its name will be * sufficient in this case. */ struct SafeToDoFooWith {} /* This type has that attribute. This attribute can be obtained at compile * time by the __traits(getAttributes) syntax. */ SafeToDoFooWith struct Struct {} /* This type does not have that attribute. */ struct AnotherStruct {} /* This template is not directly related. (I expect it to be in Phobos; maybe * it's already there. (?)) */ template hasAttribute(T, AttributeInQuestion) { bool does_have() { /* UDAs can be obtained by __traits(getAttributes). This loop is a * linear search. */ foreach (t; __traits(getAttributes, T)) { if (typeid(t) is typeid(AttributeInQuestion)) { return true; } } return false; } enum hasAttribute = does_have(); } /* This is a function that demonstrates how UDAs can affect code. */ void foo(T)(T parameter) { /* UDA are a fully compile-time feature. */ static if (hasAttribute!(T, SafeToDoFooWith)) { writefln("'%s' can safely be copied. Copying...", T.stringof); T theCopy = parameter; /* ... the rest of the algorithm ... */ } else { writefln("It is not safe to copy '%s'. Must use a different algorithm.", T.stringof); /* ... another algorithm ... */ } } void main() { auto y = Struct(); foo(y); auto by = AnotherStruct(); foo(by); } The following program demonstrates how to have multiple attributes as well as how to test for the presence of a particular attribute value. import std.stdio; /* Whether one of the attributes matches the specified type and value. */ bool hasAttributeValue(T, D)(D value) { foreach (t; __traits(getAttributes, T)) { static if (is (typeof(t) == D)) { if (t == value) { return true; } } } return false; } /* The attributes of this type are two fundamental values. */ (42, "hello") struct Struct {} void foo(T)(T obj) { static if (hasAttributeValue!T(42) && hasAttributeValue!T("hello")) { writeln("Has both attribute values"); } else { writeln("Nope..."); } } void main() { Struct a = Struct(); foo(a); } Ali
Jan 16 2013
next sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Thursday, 17 January 2013 at 04:38:14 UTC, Ali Çehreli wrote:
 On 01/16/2013 05:59 PM, Joseph Cassman wrote:
 I was wondering what the syntax is for user defined attributes 
 (I.e. bug 9222) implemented in release 2.061. I was still 
 unclear after reading the thread 
 forum.dlang.org/thread/k7afq628321 digitalmars.com.

 Thanks for the help

 Joseph
The following is the code that I had used for experimenting with UDAs:
This is by far the most comprehensive explanation of how to use them that I've seen so far. Still a couple questions. Do the structs have to be empty? (Do they have to be structs?) If they don't and you add code, can that code help/add or modify the attributed object (or can it at all?). Seems somehow in my mind there's two approaches to how the attributes work Define in one place, it modifies what it attaches to. This would be good for like serialization, perhaps adding unique functions for a particular set of jobs. struct Serialize { //assuming it's mixed in similar to a mixin template. void write(R)() if (isOutputRange!(R)) { //foreach over all elements and and save them, or //on items marked with an attribute to be saved } } Serialize struct S { //write appended in silently from UDA int x; } Used definition(s) where functions need to (statically) recognize them to interact with them. This is what currently it seems like it's doing, which is simpler to understand and integrate, but somehow only feels like half the formula. struct Serialize {} struct S { Serialize int x; } void write(R, S)(R outputRange, S inputStruct) if (isOutputRange!(R)) { //foreach, if variable(s) have Serialize then we write it. }
Jan 16 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/16/2013 09:45 PM, Era Scarecrow wrote:

 (Do they have to be structs?) If they
 don't and you add code, can that code help/add or modify the attributed
 object (or can it at all?).
It looks like some mixin magic can be used.
 Do the structs have to be empty?
They can have members. getAttributes preserves the types and values of the attributes. It returns a tuple. With the warning that I don't have any experience with attributes, the following program uses an attribute type that has a member to indicate the number of times that a variable must be serialized. (Stupid idea. :)) import std.stdio; struct Serialize { size_t count; } struct S { Serialize(3) int x; int y; Serialize(2) int z; } void foo(T)(T s) { foreach (member; __traits(allMembers, T)) { foreach (attr; __traits(getAttributes, mixin(T.stringof ~ '.' ~ member))) { if (typeid(attr) is typeid(Serialize)) { writefln("%s has %s", member, attr); writefln("must serialize %s %s times", member, attr.count); foreach (count; 0 .. attr.count) { writefln(" serializing %s", member); } } } } } void main() { auto s = S(); foo(s); } The output shows that only x and z are serialized according to their respective serialization counts: x has Serialize(3) must serialize x 3 times serializing x serializing x serializing x z has Serialize(2) must serialize z 2 times serializing z serializing z Ali
Jan 16 2013
parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Thursday, 17 January 2013 at 06:55:57 UTC, Ali Çehreli wrote:
 On 01/16/2013 09:45 PM, Era Scarecrow wrote:

 (Do they have to be structs?) If they don't and you add code, 
 can that code help/add or modify the attributed object (or can 
 it at all?).
It looks like some mixin magic can be used.
Hmm a good example would help.
 Do the structs have to be empty?
They can have members. getAttributes preserves the types and values of the attributes. It returns a tuple. With the warning that I don't have any experience with attributes, the following program uses an attribute type that has a member to indicate the number of times that a variable must be serialized. (Stupid idea. :))
Actually it does show quite a bit of how to make it useful (even if it's in a silly way); But it isn't adding anything to S directly and only during compile-time does it have any promise of use; Which is enough by itself if need be. Having arguments you can put into the struct does mean it can be useful in other ways, including perhaps having methods where it can do calculations for you on the side since it's CTFE. I suppose next we need a section that describes how to convert one piece of code to use UDA's, the thought process behind it and how it's more useful that way. Oh yes, do UDA's only work on types? or do they work on functions/methods/delegates too? If you have it on a function how could that be useful? I get the feeling the UDA will be a good topic at DConf, and an article to be added to dlang.
Jan 16 2013
next sibling parent "mist" <none none.none> writes:
UDAs very design point is to never change type they are attached 
to.
If you want to inject code in a class/struct at compile-time, 
template mixins are supposed tools.
Jan 17 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-01-17 08:20, Era Scarecrow wrote:

   Oh yes, do UDA's only work on types? or do they work on
 functions/methods/delegates too? If you have it on a function how could
 that be useful?
You can basically attach an UDA to any declaration. I think the exception is parameters. -- /Jacob Carlborg
Jan 17 2013
prev sibling parent "Joseph Cassman" <jc7919 outlook.com> writes:
On Thursday, 17 January 2013 at 04:38:14 UTC, Ali Çehreli wrote:
 On 01/16/2013 05:59 PM, Joseph Cassman wrote:
[...]
 /* This template is not directly related. (I expect it to be in 
 Phobos; maybe
  * it's already there. (?))
  */
 template hasAttribute(T, AttributeInQuestion)
[...] Ali hasAttribute is an interesting encapsulation of UDA's usage. Will probably make use of the idea. Thanks for the practical examples of usage. Joseph
Jan 17 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-17 02:59, Joseph Cassman wrote:
 I was wondering what the syntax is for user defined attributes (i.e. bug
 9222) implemented in release 2.061. I was still unclear after reading
 the thread forum.dlang.org/thread/k7afq6$2832$1 digitalmars.com.
Here's the documentation: http://dlang.org/attribute.html#uda Ali did a pretty good explanation as well. You can see how I used it for my serialization library: https://github.com/jacob-carlborg/mambo/blob/master/mambo/core/Attribute.d https://github.com/jacob-carlborg/mambo/blob/master/mambo/serialization/Serializer.d#L1481 -- /Jacob Carlborg
Jan 16 2013
parent "Joseph Cassman" <jc7919 outlook.com> writes:
On Thursday, 17 January 2013 at 07:27:35 UTC, Jacob Carlborg 
wrote:
 On 2013-01-17 02:59, Joseph Cassman wrote:
 I was wondering what the syntax is for user defined attributes 
 (i.e. bug
 9222) implemented in release 2.061. I was still unclear after 
 reading
 the thread 
 forum.dlang.org/thread/k7afq6$2832$1 digitalmars.com.
Here's the documentation: http://dlang.org/attribute.html#uda Ali did a pretty good explanation as well. You can see how I used it for my serialization library: https://github.com/jacob-carlborg/mambo/blob/master/mambo/core/Attribute.d https://github.com/jacob-carlborg/mambo/blob/master/mambo/serialization/Serializer.d#L1481
Couldn't find the documentation location. Thanks for the links. Joseph
Jan 17 2013