Thread overview
UDA: getAttributes does not play well with topleof
Dec 17, 2012
d coder
Dec 17, 2012
Jacob Carlborg
Dec 17, 2012
d coder
Dec 17, 2012
Jacob Carlborg
Dec 17, 2012
Walter Bright
Dec 17, 2012
d coder
Dec 17, 2012
Walter Bright
Dec 18, 2012
d coder
December 17, 2012
Greetings

I am trying out the new UDA functionality in the github dmd. I wanted to find out what different fields of a class carry a particular attribute. So I tried to look at the set of attributes on all the fields returned by tupleof. Interestingly I got nothing. On the other hand, when I explicitly specify a particular field in the object, the attribute is getting printed nicely on my screen.

So my question is: Is this a bug in DMD, or am I doing something plainly wrong?

If this is not a bug, I want to find out if there would be a way to find what different fields of a class carry a given attribute?

Thanks and Regards
- Puneet


template Tuple(T...) {
  alias T Tuple;
}

enum Bar;
class Foo {
  @Bar int a;
  int b;
}

void main() {
  Foo foo = new Foo;
  foreach(ref l; foo.tupleof) {
    alias Tuple!(__traits(getAttributes, l)) tp;
    pragma(msg, tp); // prints nothing
  }
  alias Tuple!(__traits(getAttributes, foo.a)) tp;
  pragma(msg, tp);             // prints (Bar)
}


December 17, 2012
On 2012-12-17 12:55, d coder wrote:

> template Tuple(T...) {
>    alias T Tuple;
> }
>
> enum Bar;
> class Foo {
>    @Bar int a;
>    int b;
> }
>
> void main() {
>    Foo foo = new Foo;
>    foreach(ref l; foo.tupleof) {
>      alias Tuple!(__traits(getAttributes, l)) tp;
>      pragma(msg, tp);// prints nothing
>    }
>    alias Tuple!(__traits(getAttributes, foo.a)) tp;
>    pragma(msg, tp);             // prints (Bar)
> }
>

Try something like this:

foreach (i, dummy, foo.tupleof)
{
    alias Tuple!(__traits(getAttributes, foo.tupleof[i])) tp;
    pragma(msg, tp);
}

-- 
/Jacob Carlborg
December 17, 2012
> Try something like this:
>
> foreach (i, dummy; foo.tupleof)
> {
>     alias Tuple!(__traits(getAttributes, foo.tupleof[i])) tp;
>     pragma(msg, tp);
> }
>
>
Ok so that is because ref does not work with foreach on tuples. Somehow I
thought that got fixed.
Anyways, with your suggestion I get a strange error.

Error: first argument is not a symbol
tuple(false)

Regards
- Puneet


December 17, 2012
On 2012-12-17 15:44, d coder wrote:

> Error: first argument is not a symbol
> tuple(false)
>
> Regards
> - Puneet
>

Then I don't know.

-- 
/Jacob Carlborg
December 17, 2012
On 12/17/2012 3:55 AM, d coder wrote:
> So my question is: Is this a bug in DMD, or am I doing something plainly wrong?

You're doing something wrong. Consider:

@Bar int i = 3;
int x = i;

The UDA does not get transferred to x. This is why your loop:

foreach(ref l; foo.tupleof)

does not transfer the UDAs to l.

December 17, 2012
On Mon, Dec 17, 2012 at 9:56 PM, Walter Bright <newshound2@digitalmars.com>wrote:

> On 12/17/2012 3:55 AM, d coder wrote:
>
>> So my question is: Is this a bug in DMD, or am I doing something plainly wrong?
>>
>
> You're doing something wrong. Consider:
>
> @Bar int i = 3;
> int x = i;
>
> The UDA does not get transferred to x. This is why your loop:
>
> foreach(ref l; foo.tupleof)
>
> does not transfer the UDAs to l.
>
>
But Walter, even the code below does not work.
Error: first argument is not a symbol
tuple(false)


template Tuple(T...) {
  alias T Tuple;
}

enum Bar;
class Foo {
  @Bar int a;
}

void main()
{
  Foo foo = new Foo;
  alias Tuple!(__traits(getAttributes, foo.tupleof[0])) tp;
  pragma(msg, tp);
}


December 17, 2012
On 12/17/2012 8:40 AM, d coder wrote:
> But Walter, even the code below does not work.
> Error: first argument is not a symbol
> tuple(false)

That's right, msg is undefined!!


> template Tuple(T...) {
>    alias T Tuple;
> }
>
> enum Bar;
> class Foo {
>    @Bar int a;
> }
>
> void main()
> {
>    Foo foo = new Foo;
>    alias Tuple!(__traits(getAttributes, foo.tupleof[0])) tp;
>    pragma(msg, tp);
            ^^^
> }

December 18, 2012
Greetings

I thought I would be able to use allMembers/getMembers traits to access the attributes of all the members of a class. But that fails me if some members of the class are private.

Consider the code pasted below -- I get en error:

B.d(5): Error: class A.Foo member bar is not accessible

And so it seems it is essential that tupleof works with getAttributes, since tupleof does not care for access protection.

I have filed a bug on Budzilla. http://d.puremagic.com/issues/show_bug.cgi?id=9178

Regards
- Puneet

module A;
enum Boo;
class Foo {
  private @Boo int bar;
}

module B;
void main() {
  import A;
  Foo foo = new Foo;
  static if(__traits(getProtection, __traits(getMember, foo, "bar"))  //
<-- can not access foo.bar
    == "public")
    {
      // Check for attribute Boo and proceed
    }
}