digitalmars.D.learn - UDA syntax
- Joseph Cassman (6/6) Jan 16 2013 I was wondering what the syntax is for user defined attributes
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (96/101) Jan 16 2013 The following is the code that I had used for experimenting with UDAs:
- Era Scarecrow (35/46) Jan 16 2013 This is by far the most comprehensive explanation of how to use
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (51/55) Jan 16 2013 They can have members. getAttributes preserves the types and values of
- Era Scarecrow (17/29) Jan 16 2013 Actually it does show quite a bit of how to make it useful (even
- mist (4/4) Jan 17 2013 UDAs very design point is to never change type they are attached
- Jacob Carlborg (5/8) Jan 17 2013 You can basically attach an UDA to any declaration. I think the
- Joseph Cassman (8/14) Jan 17 2013 [...]
- Jacob Carlborg (9/12) Jan 16 2013 Here's the documentation:
- Joseph Cassman (4/17) Jan 17 2013 Couldn't find the documentation location. Thanks for the links.
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
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 JosephThe 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
On Thursday, 17 January 2013 at 04:38:14 UTC, Ali Çehreli wrote:On 01/16/2013 05:59 PM, Joseph Cassman wrote: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. }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 JosephThe following is the code that I had used for experimenting with UDAs:
Jan 16 2013
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
On Thursday, 17 January 2013 at 06:55:57 UTC, Ali Çehreli wrote:On 01/16/2013 09:45 PM, Era Scarecrow wrote:Hmm a good example would help.(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.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.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. :))
Jan 16 2013
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
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
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
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
On Thursday, 17 January 2013 at 07:27:35 UTC, Jacob Carlborg wrote:On 2013-01-17 02:59, Joseph Cassman wrote:Couldn't find the documentation location. Thanks for the links. JosephI 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
Jan 17 2013