digitalmars.D.learn - Class Data Members Name Reflection
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (17/17) Jun 10 2014 Is there a way to iterate over the symbolic names of the data
- Adam D. Ruppe (12/12) Jun 10 2014 Two options: do allMembers and filter it out to only be data
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (19/25) Jun 10 2014 Ok.
- Adam D. Ruppe (22/24) Jun 10 2014 No trait, more like an is thing to see if the thing has an init.
- Kapps (6/18) Jun 10 2014 You may not want to use stringof for this, because stringof is
- Dicebot (17/34) Jun 10 2014 I am not sure I understand the question. Does this help?
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (4/20) Jun 10 2014 Exactly what I wanted!
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (1/4) Jun 10 2014 Correction: I mean serve *us*
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (10/51) Jun 10 2014 Notice that A.init.tupleof segfaults for classes so that is _not_
- Kapps (9/11) Jun 10 2014 There's no need to use .init:
Is there a way to iterate over the symbolic names of the data members of a class instance? I'm currently using .tupleof to get its values (and in turn types) to implement pretty printing to multiple backends (currently testing HTML) using as much of D's compile time reflection as possible: https://github.com/nordlow/justd/blob/master/pprint.d I've currently defined mappings from InputRanges of Aggregates (tuples, structs, and classes) to HTML tables where - the aggregate members are mapped to table columns (and their types in turn two column headers) and - range elements to rows and I would like to perfect the output by also propagating the member names to the column headings. I'm aware of __traits(allMembers, Type) but those return more than .tupleof does. Help please.
Jun 10 2014
Two options: do allMembers and filter it out to only be data members, or do some slicing of tupleof.stringof: S s; foreach(idx, member; s.tupleof) { writeln("Name: ", s.tupleof[idx].stringof[2..$]); } The tupleof[idx] inside the loop is important instead of just using member because then you get the name, then the slicing is because you get: s.foo for example, and you want to slice off the "s." to leave just the name.
Jun 10 2014
On Tuesday, 10 June 2014 at 16:13:31 UTC, Adam D. Ruppe wrote:Two options: do allMembers and filter it out to only be data members, or do some slicing of tupleof.stringof:What trait should I use to filter out data members?S s; foreach(idx, member; s.tupleof) { writeln("Name: ", s.tupleof[idx].stringof[2..$]); }Ok. I tried foreach (ix, memb; arg.args[0].front.tupleof) { import std.stdio: writeln; writeln(arg.args[0].front.tupleof[ix].stringof); } Almost there...except that the print seems to verbose and bit funny: ref FKind __tup4778 = front(arg._args_field_0); , __tup4778.kindName ref FKind __tup4779 = front(arg._args_field_0); , __tup4779.description ref FKind __tup4780 = front(arg._args_field_0); , __tup4780.wikiURL ref FKind __tup4781 = front(arg._args_field_0); Did I do something wrong?
Jun 10 2014
On Tuesday, 10 June 2014 at 16:30:52 UTC, Nordlöw wrote:What trait should I use to filter out data members?No trait, more like an is thing to see if the thing has an init. I think static if(is(typeof(__traits(getMember, Thing, name).init)) { } will do it. (BTW the sample chapter of my book talks about reflection, I think I talked about some of this in there: http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book )foreach (ix, memb; arg.args[0].front.tupleof)Eeek, I actually used s for a reason there - it gives you a simple name that is easily repeated and filtered. The nasty string you're seeing is the name of a compiler-generated temporary variable in the foreach. That said, your field names are in there at the end, so another option would be to run it through lastIndexOf(".") and then slice to that. So it works backward to the dot and slices off the rest of the string. string s = arg.args[0].front.tupleof[idx].stringof; auto dotIndex = s.lastIndexOf("."); assert(dotIndex >= 0); // it ought to be there anyway auto name = s[dotIndex + 1 .. $]; // slice off the temp name, whatever it is
Jun 10 2014
On Tuesday, 10 June 2014 at 16:13:31 UTC, Adam D. Ruppe wrote:Two options: do allMembers and filter it out to only be data members, or do some slicing of tupleof.stringof: S s; foreach(idx, member; s.tupleof) { writeln("Name: ", s.tupleof[idx].stringof[2..$]); } The tupleof[idx] inside the loop is important instead of just using member because then you get the name, then the slicing is because you get: s.foo for example, and you want to slice off the "s." to leave just the name.You may not want to use stringof for this, because stringof is explicitly defined as being able to change across versions, and no actual format is defined. Instead use __traits(identifier, s.tupleof[idx]). Also note that .tupleof will not return static fields.
Jun 10 2014
On Tuesday, 10 June 2014 at 16:10:09 UTC, Nordlöw wrote:Is there a way to iterate over the symbolic names of the data members of a class instance? I'm currently using .tupleof to get its values (and in turn types) to implement pretty printing to multiple backends (currently testing HTML) using as much of D's compile time reflection as possible: https://github.com/nordlow/justd/blob/master/pprint.d I've currently defined mappings from InputRanges of Aggregates (tuples, structs, and classes) to HTML tables where - the aggregate members are mapped to table columns (and their types in turn two column headers) and - range elements to rows and I would like to perfect the output by also propagating the member names to the column headings. I'm aware of __traits(allMembers, Type) but those return more than .tupleof does. Help please.I am not sure I understand the question. Does this help? struct A { int x; double y; } void main() { foreach (idx, elem; A.init.tupleof) { pragma(msg, __traits(identifier, A.tupleof[idx])); } } // output: // x // y
Jun 10 2014
I am not sure I understand the question. Does this help? struct A { int x; double y; } void main() { foreach (idx, elem; A.init.tupleof) { pragma(msg, __traits(identifier, A.tupleof[idx])); } } // output: // x // yExactly what I wanted! BTW: Can DMD serve use file and line location of user defined type aswell? Thx!
Jun 10 2014
BTW: Can DMD serve use file and line location of user defined type aswell? Thx!Correction: I mean serve *us*
Jun 10 2014
On Tuesday, 10 June 2014 at 17:29:35 UTC, Dicebot wrote:On Tuesday, 10 June 2014 at 16:10:09 UTC, Nordlöw wrote:Notice that A.init.tupleof segfaults for classes so that is _not_ an adviced solution in a generic solution! But fortunately I always have an instance, say a, of A available in the pprint functions so I just use a.tupleof instead! Now it works! I'll update pprint.d later today! I'll further extract away the dumb dependencies for pprint.d in the upcoming days so it can be reused later on. Thanks you all!Is there a way to iterate over the symbolic names of the data members of a class instance? I'm currently using .tupleof to get its values (and in turn types) to implement pretty printing to multiple backends (currently testing HTML) using as much of D's compile time reflection as possible: https://github.com/nordlow/justd/blob/master/pprint.d I've currently defined mappings from InputRanges of Aggregates (tuples, structs, and classes) to HTML tables where - the aggregate members are mapped to table columns (and their types in turn two column headers) and - range elements to rows and I would like to perfect the output by also propagating the member names to the column headings. I'm aware of __traits(allMembers, Type) but those return more than .tupleof does. Help please.I am not sure I understand the question. Does this help? struct A { int x; double y; } void main() { foreach (idx, elem; A.init.tupleof) { pragma(msg, __traits(identifier, A.tupleof[idx])); } } // output: // x // y
Jun 10 2014
On Tuesday, 10 June 2014 at 20:01:37 UTC, Nordlöw wrote:Notice that A.init.tupleof segfaults for classes so that is _not_ an adviced solution in a generic solution!There's no need to use .init: import std.stdio; struct Foo { int a, b; } void main() { writeln(__traits(identifier, Foo.tupleof[0])); }
Jun 10 2014