Thread overview
UDA initialize a user defined type attribute field
Feb 18, 2014
Arjan
Feb 18, 2014
Adam D. Ruppe
Feb 19, 2014
Arjan
Feb 19, 2014
bearophile
Feb 19, 2014
Ali Çehreli
February 18, 2014
When a user defined type is used as an attribute like this:
// the attribute
struct MyAttrib
{
    immutable string name;
    imuttable int sz;
    immutable string defaultvalue;
}

// using the attribute
class Data
{
    // field 'id' has attribute MyAttrib with name and sz set to 'fancy name'
    // and 10 resp.
    @MyAttrib( "fancy name", 10 )
    long id;
    ...
}


But how do I only set the MyAttrib.defaultvalue?

class OtherData
{
    //@MyAttrib( ??defaultvalue = "null" ?? )
    //@MyAttrib( string.init, int.init, "null" ) //seems to work?
    long id;
    ...
}

MyAttrib instances may be initialized like this:

auto myattrib = { defaultvalue:"null" };

But this seems not possible when using MyAttrib as attribute.
February 18, 2014
On Tuesday, 18 February 2014 at 23:43:56 UTC, Arjan wrote:
> But how do I only set the MyAttrib.defaultvalue?

You could do it by adding a constructor to MyAttrib that only takes one string and fills it in that way.
February 19, 2014
On Tuesday, 18 February 2014 at 23:46:28 UTC, Adam D. Ruppe wrote:
> On Tuesday, 18 February 2014 at 23:43:56 UTC, Arjan wrote:
>> But how do I only set the MyAttrib.defaultvalue?
>
> You could do it by adding a constructor to MyAttrib that only takes one string and fills it in that way.

But what happens than when only the first field 'name' is used in MyAttrib like this:

class OtherData
{
    @MyAttrib( "fancy name" )
    long id;
    ...
}

I guess the field MyAttrib.defaultvalue will be assigned the value "fancy name"?

February 19, 2014
Arjan:

> MyAttrib instances may be initialized like this:
>
> auto myattrib = { defaultvalue:"null" };
>
> But this seems not possible when using MyAttrib as attribute.

This could become a D enhancement request.


> I guess the field MyAttrib.defaultvalue will be assigned the value "fancy name"?

Unfortunately D doesn't have named arguments.

You can use chains, returning this from some methods:

MyAttrib().setName("Foo").setSz(10).setDefaultValue("Bar")

Bye,
bearophile
February 19, 2014
On 02/18/2014 03:43 PM, Arjan wrote:
> When a user defined type is used as an attribute like this:
> // the attribute
> struct MyAttrib
> {
>      immutable string name;
>      imuttable int sz;
>      immutable string defaultvalue;
> }
>
> // using the attribute
> class Data
> {
>      // field 'id' has attribute MyAttrib with name and sz set to 'fancy
> name'
>      // and 10 resp.
>      @MyAttrib( "fancy name", 10 )
>      long id;
>      ...
> }
>
>
> But how do I only set the MyAttrib.defaultvalue?
>
> class OtherData
> {
>      //@MyAttrib( ??defaultvalue = "null" ?? )
>      //@MyAttrib( string.init, int.init, "null" ) //seems to work?
>      long id;
>      ...
> }
>
> MyAttrib instances may be initialized like this:
>
> auto myattrib = { defaultvalue:"null" };
>
> But this seems not possible when using MyAttrib as attribute.

This problem has nothing to do with UDAs and can be solved similar to regular cases, e.g. by using a factory function:

// the attribute
struct MyAttrib
{
    immutable string name;
    immutable int sz;
    immutable string defaultvalue;
}

MyAttrib makeMyAttribWithDefaultValue(string defaultValue)
{
    return MyAttrib(MyAttrib.name.init, MyAttrib.sz.init, defaultValue);
}

// using the attribute
class Data
{
    // field 'id' has attribute MyAttrib with name and sz set to 'fancy name'
    // and 10 resp.
    @MyAttrib( "fancy name", 10 )
    long id;

    @makeMyAttribWithDefaultValue("hello")
    int i;
}

void main()
{
    pragma(msg, __traits(getAttributes, Data.id));
    pragma(msg, __traits(getAttributes, Data.i));
}

Ali