www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Traits: getting all *public* members of a class?

reply "Q" <q example.com> writes:
Hi there, I want to iterate over all the public members of a 
class, but I've hit a stumbling block when the class resides in a 
different module and also contains private members. For example:

$ cat foo.d
class Foo {
     private int x;
     public int y;
}

$ cat main.d
import foo;

void main() {
     foreach (mem; __traits(allMembers, Foo)) {
         enum prot = __traits(getProtection, __traits(getMember, 
Foo.init, mem));
         static if (prot == "public") {
             // ...
         }
     }
}

However, the compiler gives me the following error message:

$ dmd main foo
main.d(5): Error: class foo.Foo member x is not accessible

Since I'm not interested in the private members, is there any way 
to ignore them and only iterate over the public members? Or is 
reflection in this way disallowed when the target class lives in 
a different module?
Jun 08 2013
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
You could probably throw in a traits(compiles) right above.

foreach(...) {
// or maybe compiles, getProtection(getMember))
static if(__traits(compiles, __traits(getMember,Foo.init, mem)) {
         enum prot = __traits(getProtection, __traits(getMember,
Foo.init, mem));
// and so on
}
}

I haven't actually tried this but generally static if(compiles) 
is a way to work around unwanted error messages.
Jun 08 2013
prev sibling parent reply "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Saturday, 8 June 2013 at 13:57:13 UTC, Q wrote:
 Hi there, I want to iterate over all the public members of a 
 class.
It is a known problem. The workaround is to use is(typeof()): void main() { foreach (mem; __traits(allMembers, Foo)) { static if (is(typeof( __traits(getMember, Foo.init, mem) ))) { enum prot = __traits(getProtection, __traits(getMember, Foo.init, mem)); static if (prot == "public") { pragma(msg, mem); } } } }
Jun 08 2013
parent "Q" <q example.com> writes:
On Saturday, 8 June 2013 at 14:06:32 UTC, Andrej Mitrovic wrote:
 On Saturday, 8 June 2013 at 13:57:13 UTC, Q wrote:
 Hi there, I want to iterate over all the public members of a 
 class.
It is a known problem. The workaround is to use is(typeof()): void main() { foreach (mem; __traits(allMembers, Foo)) { static if (is(typeof( __traits(getMember, Foo.init, mem) ))) { enum prot = __traits(getProtection, __traits(getMember, Foo.init, mem)); static if (prot == "public") { pragma(msg, mem); } } } }
This worked perfectly. Thank you!
Jun 08 2013