www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Getting the current module as a symbol

reply Mithun Hunsur <me philpax.me> writes:
Hi all,

I'm looking for the equivalent of `typeof(this)` in module scope 
(so that it gets the current module). My use-case is iterating 
over the members of the module - right now I'm doing

`mixin(iterateOverModule!(module.name.here));`

but in the interests of keeping the code simple to maintain, I'd 
like to be able to get the current module automatically.

Is this possible? A cursory Google search didn't turn up 
anything, and `this` has no meaning in module scope.
Apr 12 2016
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 April 2016 at 13:44:07 UTC, Mithun Hunsur wrote:
 I'm looking for the equivalent of `typeof(this)` in module 
 scope (so that it gets the current module).
The trick I use is `mixin(__MODULE__)`. I also mentioned this in my book https://www.packtpub.com/application-development/d-cookbook the free sample is the reflection chapter which has a few tricks like this.
Apr 12 2016
parent Mithun Hunsur <me philpax.me> writes:
On Tuesday, 12 April 2016 at 14:22:22 UTC, Adam D. Ruppe wrote:
 On Tuesday, 12 April 2016 at 13:44:07 UTC, Mithun Hunsur wrote:
 I'm looking for the equivalent of `typeof(this)` in module 
 scope (so that it gets the current module).
The trick I use is `mixin(__MODULE__)`. I also mentioned this in my book https://www.packtpub.com/application-development/d-cookbook the free sample is the reflection chapter which has a few tricks like this.
Thanks! That works great. For anyone else stumbling across this in the future: if your mixin is in another file, you need to pass in __MODULE__ as a default argument: mixin template ATemplate(string moduleName = __module__) { mixin(moduleName); // Is a reference to the module that instantiated it. } This can be a little finicky, so I'd still like to see language-level support for getting the current module (perhaps defining 'this' at module-level to be the current module). I'll probably make a post in the main group for it - thanks for the help :)
Apr 12 2016
prev sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Tuesday, 12 April 2016 at 13:44:07 UTC, Mithun Hunsur wrote:
 Hi all,

 I'm looking for the equivalent of `typeof(this)` in module 
 scope (so that it gets the current module). My use-case is 
 iterating over the members of the module - right now I'm doing

 `mixin(iterateOverModule!(module.name.here));`

 but in the interests of keeping the code simple to maintain, 
 I'd like to be able to get the current module automatically.

 Is this possible? A cursory Google search didn't turn up 
 anything, and `this` has no meaning in module scope.
Have you tried __traits(parent, someTopLevelSymbol)? Walking the __traits(parent) chain should get you to a module either way, I think.
Apr 12 2016
parent reply Mithun Hunsur <me philpax.me> writes:
On Wednesday, 13 April 2016 at 05:30:27 UTC, Vladimir Panteleev 
wrote:
 On Tuesday, 12 April 2016 at 13:44:07 UTC, Mithun Hunsur wrote:
 Hi all,

 I'm looking for the equivalent of `typeof(this)` in module 
 scope (so that it gets the current module). My use-case is 
 iterating over the members of the module - right now I'm doing

 `mixin(iterateOverModule!(module.name.here));`

 but in the interests of keeping the code simple to maintain, 
 I'd like to be able to get the current module automatically.

 Is this possible? A cursory Google search didn't turn up 
 anything, and `this` has no meaning in module scope.
Have you tried __traits(parent, someTopLevelSymbol)? Walking the __traits(parent) chain should get you to a module either way, I think.
Yeah, that also works; you have to define a symbol (if you don't have one you can already use) in order to get to it, so it's a little wasteful. Still useful to know, though!
Apr 13 2016
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Wednesday, 13 April 2016 at 11:36:07 UTC, Mithun Hunsur wrote:
 Yeah, that also works; you have to define a symbol (if you 
 don't have one you can already use) in order to get to it, so 
 it's a little wasteful. Still useful to know, though!
No, it's not necessary. You should be able to walk the chain of __traits(parent) by starting with a local symbol, e.g. a lambda predicate. Have a look at std.traits.moduleName which does most of the work.
Apr 13 2016
parent Mithun Hunsur <me philpax.me> writes:
On Wednesday, 13 April 2016 at 16:58:34 UTC, Vladimir Panteleev 
wrote:
 On Wednesday, 13 April 2016 at 11:36:07 UTC, Mithun Hunsur 
 wrote:
 Yeah, that also works; you have to define a symbol (if you 
 don't have one you can already use) in order to get to it, so 
 it's a little wasteful. Still useful to know, though!
No, it's not necessary. You should be able to walk the chain of __traits(parent) by starting with a local symbol, e.g. a lambda predicate. Have a look at std.traits.moduleName which does most of the work.
Aha! That is a _very_ clever trick. :) For everyone else: __traits(parent, {}); The {} is a lambda predicate instantiated in the current scope (i.e. module scope); getting the parent of that gets you the module. If you wanted to generalise that, you could walk up the parent chain like Vladimir says - but this is perfect for my uses. Thanks again!
Apr 13 2016