Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
July 09, 2014 Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Hello, I'm looking to introspect a module, list all the members, iterate over them and filter them by kind inside of a static constructor. This is in the hope of shortening some hand-written code that is quite repetitive (adding many struct instances to an associative array in a static constructor). The code I'm trying to improve upon can be seen here: https://github.com/maximecb/Higgs/blob/master/source/ir/iir.d#L56 I've done some googling, and it seems I should be able to use the allMembers trait (http://wiki.dlang.org/Finding_all_Functions_in_a_Module), but unfortunately, the module name seems to be unrecognized, no matter which way I spell it: auto members = [__traits(allMembers, "ir.ir")]; pragma(msg, members); Produces: ir/iir.d(85): Error: argument has no members Other people seem to have run into this problem. Am I doing it wrong or is this a bug in DMD? |
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier-Boisvert | On Wednesday, 9 July 2014 at 20:04:47 UTC, Maxime Chevalier-Boisvert wrote:
> auto members = [__traits(allMembers, "ir.ir")];
> pragma(msg, members);
Have you tried without quotes?
pragma(msg, __traits(allMembers, ir.ir));
|
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to NCrashed | On Wed, 09 Jul 2014 20:07:56 +0000, NCrashed wrote:
> On Wednesday, 9 July 2014 at 20:04:47 UTC, Maxime Chevalier-Boisvert wrote:
>> auto members = [__traits(allMembers, "ir.ir")];
>> pragma(msg, members);
>
> Have you tried without quotes?
> pragma(msg, __traits(allMembers, ir.ir));
Also, looks like it should be "ir.iir"
|
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to NCrashed | On Wednesday, 9 July 2014 at 20:07:57 UTC, NCrashed wrote:
> Produces:
> ir/iir.d(85): Error: argument has no members
If module name is ir.iir: pragma(msg, __traits(allMembers, ir.iir));
|
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to NCrashed | On Wednesday, 9 July 2014 at 20:07:57 UTC, NCrashed wrote:
> On Wednesday, 9 July 2014 at 20:04:47 UTC, Maxime Chevalier-Boisvert wrote:
>> auto members = [__traits(allMembers, "ir.ir")];
>> pragma(msg, members);
>
> Have you tried without quotes?
> pragma(msg, __traits(allMembers, ir.ir));
Did need to write it without the quotes, and to add "enum" to force compile-time evaluation. It's actually ir.ops that I wanted to list the members of. Got the following snippet to work:
static this()
{
enum members = [__traits(allMembers, ir.ops)];
pragma(msg, members);
}
Prints:
["object", "ir", "jit", "OpArg", "OpInfo", "Opcode", "GET_ARG", "SET_STR", "MAKE_VALUE", "GET_WORD", "GET_TYPE", "IS_I32", ...]
|
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier-Boisvert | I got the following code to do what I want: static this() { void addOp(ref Opcode op) { assert ( op.mnem !in iir, "duplicate op name " ~ op.mnem ); iir[op.mnem] = &op; } foreach (memberName; __traits(allMembers, ir.ops)) { static if (__traits(compiles, addOp(__traits(getMember, ir.ops, memberName)))) { writeln(memberName); addOp(__traits(getMember, ir.ops, memberName)); } } } It's a bit of a hack, but it works. Is there any way to create some sort of alias for __traits(getMember, ir.ops, memberName) so that I don't have to write it out in full twice? Made some attempts but only got the compiler to complain. |
July 09, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier-Boisvert | On Wednesday, 9 July 2014 at 20:52:29 UTC, Maxime Chevalier-Boisvert wrote:
> It's a bit of a hack, but it works. Is there any way to create some sort of alias for __traits(getMember, ir.ops, memberName) so that I don't have to write it out in full twice? Made some attempts but only got the compiler to complain.
alias Alias(alias Sym) = Sym;
alias member = Alias!(__traits(getMember, ir.ops, memberName);
It does not work with normal alias because of grammar limitation afaik.
|
July 10, 2014 Re: Introspecting a Module with Traits, allMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier-Boisvert | The others have already given some answers, I just want to point out that the (free) sample chapter of my D book covers this topic too: http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book Scanning a whole module and getting everything out takes a few tricks that I talk about in there. |
Copyright © 1999-2021 by the D Language Foundation