www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - allMembers and getMember traits behavior

reply "Martin" <martinbbjerregaard gmail.com> writes:
module test;

void test()
{


     foreach (member; __traits(allMembers, Client))
     {
         pragma(msg, member); // Prints all members fine, 
including "value"
     }

     // This line fails
     static if(__traits(getProtection, __traits(getMember, 
TestClass, "value")) == "public")
     {
         pragma(msg, "value is public");
     }
     else
     {
         pragma(msg, "value is not public");
     }

}

module testclass;

class TestClass
{
private:
     int value;
}

When using the allMembers trait, the private "value" member of 
TestClass is included, but when trying to retrieve that member 
using the getMember trait, it fails to compile with test.d(13): 
Error: class main.TestClass member value is not accessible

Is that intended behavior or a bug? I can't see why the getMember 
trait should not be able to retrieve private members when 
allMembers trait is
Jun 21 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-06-21 15:04, Martin wrote:
 module test;

 void test()
 {


      foreach (member; __traits(allMembers, Client))
      {
          pragma(msg, member); // Prints all members fine, including "value"
      }

      // This line fails
      static if(__traits(getProtection, __traits(getMember, TestClass,
 "value")) == "public")
      {
          pragma(msg, "value is public");
      }
      else
      {
          pragma(msg, "value is not public");
      }

 }

 module testclass;

 class TestClass
 {
 private:
      int value;
 }

 When using the allMembers trait, the private "value" member of TestClass
 is included, but when trying to retrieve that member using the getMember
 trait, it fails to compile with test.d(13): Error: class main.TestClass
 member value is not accessible

 Is that intended behavior or a bug? I can't see why the getMember trait
 should not be able to retrieve private members when allMembers trait is
Can you use a string instead of getMember? -- /Jacob Carlborg
Jun 21 2013
parent reply "Martin" <martinbbjerregaard gmail.com> writes:
On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
 On 2013-06-21 15:04, Martin wrote:
 module test;

 void test()
 {


     foreach (member; __traits(allMembers, Client))
     {
         pragma(msg, member); // Prints all members fine, 
 including "value"
     }

     // This line fails
     static if(__traits(getProtection, __traits(getMember, 
 TestClass,
 "value")) == "public")
     {
         pragma(msg, "value is public");
     }
     else
     {
         pragma(msg, "value is not public");
     }

 }

 module testclass;

 class TestClass
 {
 private:
     int value;
 }

 When using the allMembers trait, the private "value" member of 
 TestClass
 is included, but when trying to retrieve that member using the 
 getMember
 trait, it fails to compile with test.d(13): Error: class 
 main.TestClass
 member value is not accessible

 Is that intended behavior or a bug? I can't see why the 
 getMember trait
 should not be able to retrieve private members when allMembers 
 trait is
Can you use a string instead of getMember?
You mean something like this: foreach (member; __traits(allMembers, TestClass)) { static if (member == "value") { pragma(msg, __traits(getProtection, member)); } } That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
Jun 21 2013
parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 06/21/13 15:27, Martin wrote:
 On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
 On 2013-06-21 15:04, Martin wrote:
 module test;

 void test()
 {


     foreach (member; __traits(allMembers, Client))
     {
         pragma(msg, member); // Prints all members fine, including "value"
     }

     // This line fails
     static if(__traits(getProtection, __traits(getMember, TestClass,
 "value")) == "public")
     {
         pragma(msg, "value is public");
     }
     else
     {
         pragma(msg, "value is not public");
     }

 }

 module testclass;

 class TestClass
 {
 private:
     int value;
 }

 When using the allMembers trait, the private "value" member of TestClass
 is included, but when trying to retrieve that member using the getMember
 trait, it fails to compile with test.d(13): Error: class main.TestClass
 member value is not accessible

 Is that intended behavior or a bug? I can't see why the getMember trait
 should not be able to retrieve private members when allMembers trait is
Can you use a string instead of getMember?
You mean something like this: foreach (member; __traits(allMembers, TestClass)) { static if (member == "value") { pragma(msg, __traits(getProtection, member)); } } That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
pragma(msg, __traits(getProtection, mixin("TestClass." ~ member))); artur
Jun 21 2013
parent reply "Martin" <martinbbjerregaard gmail.com> writes:
On Friday, 21 June 2013 at 13:42:44 UTC, Artur Skawina wrote:
 On 06/21/13 15:27, Martin wrote:
 On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
 On 2013-06-21 15:04, Martin wrote:
 module test;

 void test()
 {


     foreach (member; __traits(allMembers, Client))
     {
         pragma(msg, member); // Prints all members fine, 
 including "value"
     }

     // This line fails
     static if(__traits(getProtection, __traits(getMember, 
 TestClass,
 "value")) == "public")
     {
         pragma(msg, "value is public");
     }
     else
     {
         pragma(msg, "value is not public");
     }

 }

 module testclass;

 class TestClass
 {
 private:
     int value;
 }

 When using the allMembers trait, the private "value" member 
 of TestClass
 is included, but when trying to retrieve that member using 
 the getMember
 trait, it fails to compile with test.d(13): Error: class 
 main.TestClass
 member value is not accessible

 Is that intended behavior or a bug? I can't see why the 
 getMember trait
 should not be able to retrieve private members when 
 allMembers trait is
Can you use a string instead of getMember?
You mean something like this: foreach (member; __traits(allMembers, TestClass)) { static if (member == "value") { pragma(msg, __traits(getProtection, member)); } } That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
pragma(msg, __traits(getProtection, mixin("TestClass." ~ member))); artur
Thanks, that sort of works. It prints "private" but then immediately gives an error: test.d(12): Error: class main.TestClass member value is not accessible Sigh, this is DMD 2.063.2 by the way.
Jun 21 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-06-21 15:50, Martin wrote:

 Thanks, that sort of works. It prints "private" but then immediately
 gives an error:
 test.d(12): Error: class main.TestClass member value is not accessible

 Sigh, this is DMD 2.063.2 by the way.
That sucks. Time for a bugzilla report. http://d.puremagic.com/issues/ -- /Jacob Carlborg
Jun 21 2013
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 06/21/13 15:50, Martin wrote:
 On Friday, 21 June 2013 at 13:42:44 UTC, Artur Skawina wrote:
    pragma(msg, __traits(getProtection, mixin("TestClass." ~ member)));
Thanks, that sort of works. It prints "private" but then immediately gives an error: test.d(12): Error: class main.TestClass member value is not accessible Sigh, this is DMD 2.063.2 by the way.
Sorry, didn't test that one, just used the right symbol; it has the same problem as your original issue. Clearly, the getProtection trait wasn't designed with inaccesible symbols in mind. And no, 'getMember' bypassing the protection would not be a good idea (would make it too easy to mistakenly access private data in generic code). getProtection should probably just take two args, just like getMember, which would allow it to safely ignore the normal access rules. Right now, you can use 'tupleof', which bypasses the visibility attrs: alias T = TestClass; foreach (I, TYPE; typeof(T.tupleof)) { pragma(msg, __traits(getProtection, T.tupleof[I]), " ", TYPE, " ", __traits(identifier, T.tupleof[I]), ";"); } artur
Jun 21 2013