www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting the name of current module

reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
Hi,

does anyone of you know a way to get the name of the current module at
compile-time?

I have a very fragile trick, creating a temporary, mangling/demangling it and
parsing the resulting name, but it's ugly as hell and does not work so well.


I need this for a very simple reason: I have a huge string mixin which
introduces helper structs in the current scope. The user may well use the
mixin many time with common arguments, which will mix-in many times the same
structs. So, botch.

Say I have:

mixin("struct Foo {}");
//...
mixin("struct Foo {}");

My first thought was to insert a static this:

mixin("static if (!is(Foo)) struct Foo {}");
But this does not work :-( after the first mixin the code is not compiled yet,
so Foo is not a type.

But I discovered that __traits(allMembers, currentModule) _will_ contain "Foo"
after the first mixin. So I can test for the existence of Foo this way and
abort creating it a second time. But, for that to work, I need the (local!)
module name at compile-time, the one the string will be mixed in.


Philippe
Aug 26 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Philippe Sigaud:
 does anyone of you know a way to get the name of the current module at
 compile-time?
It's one of the missing pieces of the static reflection: __traits(thisModuleName) Bye, bearophile
Aug 26 2010
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, Aug 26, 2010 at 22:37, bearophile <bearophileHUGS lycos.com> wrote:

 Philippe Sigaud:
 does anyone of you know a way to get the name of the current module at
 compile-time?
It's one of the missing pieces of the static reflection: __traits(thisModuleName) I want this to return an expression tuple with all the package / module
hierarchy: "std", "stdio". That way, I can easily find the package name too... *daydreaming* Maybe a generic __traits(thisScopeName) could be interesting: at the root of a module, it gives the module name, in a function, the function name, class name, etc. Philippe
Aug 26 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
import Python
dir()

etc.. :)

I want more reflection as well, it's plenty of fun.

On Fri, Aug 27, 2010 at 12:13 AM, Philippe Sigaud
<philippe.sigaud gmail.com> wrote:
 On Thu, Aug 26, 2010 at 22:37, bearophile <bearophileHUGS lycos.com> wrot=
e:
 Philippe Sigaud:
 does anyone of you know a way to get the name of the current module at
 compile-time?
It's one of the missing pieces of the static reflection: __traits(thisModuleName)
I want this to return an expression tuple with all the package / module hierarchy:=A0 "std", "stdio". That way, I can easily find the package nam=
e

Aug 26 2010
prev sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Fri, Aug 27, 2010 at 01:09, Andrej Mitrovic
<andrej.mitrovich gmail.com>wrote:

 import Python
 dir()

 etc.. :)

 I want more reflection as well, it's plenty of fun.
I will use my mangling/demangling trick, and do it at CT using http://digitalmars.com/d/2.0/abi.html I wonder if one can get the name of function while being inside ? Ah, yes, you can: module main; import std.stdio; import std.traits; import std.demangle; void foo(int i) { double test; writeln(i.mangleof); writeln(test.mangleof); writeln(demangle(i.mangleof)); writeln(demangle(test.mangleof)); writeln(mangledName!i); writeln(mangledName!test); writeln(demangle(mangledName!i)); writeln(demangle(mangledName!test)); } void main() { foo(1); int i; double test; writeln(i.mangleof); writeln(test.mangleof); writeln(demangle(i.mangleof)); writeln(demangle(test.mangleof)); writeln(mangledName!i); writeln(mangledName!test); writeln(demangle(mangledName!i)); writeln(demangle(mangledName!test)); } Extracting 'main' or 'foo' from the right place in the mangle shouldn't be too difficult. So doing a template that alias itself to the name of the current function or module is doable. std.demangle use a try catch statement -> it's not usable at compile-time. Hmm, that pretty interesting! I was wondering how to create generic recursive functions from strings like "a + self(b)". Now, I can get the function name, replace self with it and mix the code in the right place. The built-in .mangleof property is a bit strange. Does it work correctly? Philippe
Aug 27 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Philippe Sigaud:
 I was wondering how to create generic
 recursive functions from strings like "a + self(b)". Now, I can get the
 function name, replace self with it and mix the code in the right place.
Time ago I have proposed the function name to be contained in a variable named __function__ inside every Python function, and named something like __func inside D programs. The advantage is to follow DRY, and avoid repeating the function name two times. So if later you change the name of a *self* recursive function, your program keeps working correctly (it doesn't work with mutually recursive functions, but they are quite less common in non-functional code). With it you may even create self-recursive lambdas and self-recursive delegates created from class methods. This very simple feature was appreciated by some people, but it has not seen light both in Python and D. Bye, bearophile
Aug 27 2010