digitalmars.D.learn - Phobos Members-Tuple function?
- F i L (38/38) Jan 19 2013 Is there a function in phobos which will return a Tuple of a
- bearophile (5/8) Jan 19 2013 I have not fully understood the problem, but have you tried
- F i L (10/12) Jan 19 2013 yes, that's not really relevant to my problem. 'm' in your
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (60/62) Jan 19 2013 The following program produces this output:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (13/20) Jan 19 2013 How come that function compiles without a return type? The following is
- Timon Gehr (5/25) Jan 19 2013 Not a bug. This is function return type deduction. If you return
- Timon Gehr (3/21) Jan 19 2013 This only works because Ship happens to be defined in the same module.
- F i L (6/8) Jan 19 2013 Awesome! Thanks, I wasn't expecting it to actually be as easy as
- Timon Gehr (5/13) Jan 19 2013 foreach over an enum constant is not magically unrolled statically like
- Timon Gehr (5/7) Jan 19 2013 I guess this is your problem. (The original post was confusing because
Is there a function in phobos which will return a Tuple of a Type's members, for use in a foreach statement? I need this for collecting info on all Type Members's User Attributes. Currently, I have written a recursive function which does this, but I'm looking for a more elegant solution. Let's say I have an Ship Actor class: class Ship : Actor { Bind("Stage.update") void update() { // ... } Bind("Canvas.draw") void draw() { // ... } } and I want to iterator over all it's members.. and, in turn, iterate over all their attributes. If I use "__traits(derivedMembers, Ship)" it returns a Tuple of strings, which I can't use with __traits(getAttributes, ..). So what are my options here? Ideally, I'd like to be able to do this: auto ship = new Ship; enum mbrs = membersOf(Ship); // returns Tuple foreach (m; mbrs) { enum atrs = __traits(getAttributes, m); foreach (a; atrs) { if (is(a : Bind)) Engine.bindActors(ship, a.pattern); } } Like I said, I've already accomplished this using recursion. I'm just wondering if there's an easier way (like above). Also, if recursive functions are required, I'd love to hear ideas on the best way to write a general purpose recursive function for this kind of thing.
Jan 19 2013
F i L:I need this for collecting info on all Type Members's User Attributes. Currently, I have written a recursive function which does this, but I'm looking for a more elegant solution.I have not fully understood the problem, but have you tried [__traits(getAttributes, m)] ? Bye, bearophile
Jan 19 2013
bearophile wrote:I have not fully understood the problem, but have you tried [__traits(getAttributes, m)] ?yes, that's not really relevant to my problem. 'm' in your example, can't be read at compile time, because __traits(derivedMembers, ..) returns a Tuple of strings, not Symbols. I can get the attributes of a specific member just fine, the problem is iterating over *all* members, then finding the attributes for each member. It's relatively easy to solve with recursion, I'm just trying to cover my tracks here and see if there's a better way I'm unaware of.
Jan 19 2013
On 01/19/2013 12:10 PM, F i L wrote:Is there a function in phobos which will return a Tuple of a Type's members, for use in a foreach statement?The following program produces this output: member update attribute Bind("Stage.update") Binding actor with pattern Stage.update member draw attribute Bind("Canvas.draw") Binding actor with pattern Canvas.draw member toString member toHash member opCmp member opEquals member Monitor member factory I had to use a mixin and had to move __traits(allMembers) into the foreach loop. It was necessary so that 'm' could be evaluated at compile time. I can kind of see why but one would expect your 'enum mbrs' to work as well. import std.stdio; interface Actor {} struct Bind { string pattern; } class Ship : Actor { Bind("Stage.update") void update() { // ... } Bind("Canvas.draw") void draw() { // ... } } class Engine { static bindActors(Actor, string pattern) { writefln(" Binding actor with pattern %s", pattern); } } void main() { auto ship = new Ship; alias T = typeof(ship); foreach (m; __traits(allMembers, T)) { writefln("member %s", m); enum atrs = __traits(getAttributes, mixin(T.stringof ~ "." ~ m)); foreach (a; atrs) { writefln(" attribute %s", a); if (is(typeof(a) == Bind)) Engine.bindActors(ship, a.pattern); } } } Ali
Jan 19 2013
On 01/19/2013 06:41 PM, Ali Çehreli wrote:class Engine { static bindActors(Actor, string pattern) { writefln(" Binding actor with pattern %s", pattern); } }How come that function compiles without a return type? The following is a bug, right? class C { static foo() // <-- no return type; void is assumed {} } void main() { static assert(is(typeof(C.foo()) == void)); } Ali
Jan 19 2013
On 01/20/2013 03:59 AM, Ali Çehreli wrote:On 01/19/2013 06:41 PM, Ali Çehreli wrote: > class Engine > { > static bindActors(Actor, string pattern) > { > writefln(" Binding actor with pattern %s", pattern); > } > } How come that function compiles without a return type? The following is a bug, right? class C { static foo() // <-- no return type; void is assumed {} } void main() { static assert(is(typeof(C.foo()) == void)); } AliNot a bug. This is function return type deduction. If you return something from foo, then the return type will change. What is often missed is that 'auto' does not mean anything. It exists just to make the parser happy.
Jan 19 2013
On 01/20/2013 03:41 AM, Ali Çehreli wrote:... void main() { auto ship = new Ship; alias T = typeof(ship); foreach (m; __traits(allMembers, T)) { writefln("member %s", m); enum atrs = __traits(getAttributes, mixin(T.stringof ~ "." ~ m));This only works because Ship happens to be defined in the same module. Use __traits(getMember, T, m) instead of the mixin.foreach (a; atrs) { writefln(" attribute %s", a); if (is(typeof(a) == Bind)) Engine.bindActors(ship, a.pattern); } } } Ali
Jan 19 2013
Ali Çehreli wrote:The following program produces this output: [...code...]Awesome! Thanks, I wasn't expecting it to actually be as easy as that. I tried all sort of difference combinations with __traits(allMembers, ..) but it looks like I just needed to move it into the foreach loop itself. I wounder why there's a difference when assigning to an enum...
Jan 19 2013
On 01/20/2013 04:55 AM, F i L wrote:Ali Çehreli wrote:foreach over an enum constant is not magically unrolled statically like foreach over a sequence ("TypeTuple") is. (The somewhat related fact that static foreach over a sequence of enum values does not work is a compiler bug.)The following program produces this output: [...code...]Awesome! Thanks, I wasn't expecting it to actually be as easy as that. I tried all sort of difference combinations with __traits(allMembers, ..) but it looks like I just needed to move it into the foreach loop itself. I wounder why there's a difference when assigning to an enum...
Jan 19 2013
On 01/20/2013 06:59 AM, Timon Gehr wrote:The somewhat related fact that static foreach over a sequence of enum values does not work is a compiler bug.I guess this is your problem. (The original post was confusing because it contained pseudo code.) To prevent confusion in the future, please always post the full code snippet.
Jan 19 2013