www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - UDA: getAttributes does not play well with topleof

reply d coder <dlang.coder gmail.com> writes:
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)
}
Dec 17 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
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
Dec 17 2012
parent reply d coder <dlang.coder gmail.com> writes:
 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
Dec 17 2012
parent Jacob Carlborg <doob me.com> writes:
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
Dec 17 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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.
Dec 17 2012
parent reply d coder <dlang.coder gmail.com> writes:
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); }
Dec 17 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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);
^^^
 }
Dec 17 2012
parent d coder <dlang.coder gmail.com> writes:
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
    }
}
Dec 18 2012