www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting module of a class

reply "Bill Baxter" <wbaxter gmail.com> writes:
I find myself sometimes wanting to get an alias to the module
namespace that a given type came from.

The reason is this:  these days it's en vogue to make classes contain
as few functions as necessary, and to write everything else as
non-member functions.  The problem is that when you are using
BigCoreDataStructure a lot in your program it's natural to import that
from other modules and in the end you can lose sight of which module
BigCoreDataStructure came from (it could be aliased to something else
like "BCDS" in your current namespace for instance.)

But now you have a problem because you have access to BCDS but you
also want to get at his auxillary non-member functions.    But those
didn't get imported because they would gum up the namespace.

I'm thinking it would be nice if you could do something like
ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
functions in BCDS's module whatever that may be.

I think types do have the information of which module they originated
in, so technically it should be possible.  Has anyone written a
routine that can do this?

--bb
Oct 17 2008
next sibling parent reply Don <nospam nospam.com.au> writes:
Bill Baxter wrote:
 I find myself sometimes wanting to get an alias to the module
 namespace that a given type came from.
 
 The reason is this:  these days it's en vogue to make classes contain
 as few functions as necessary, and to write everything else as
 non-member functions.  The problem is that when you are using
 BigCoreDataStructure a lot in your program it's natural to import that
 from other modules and in the end you can lose sight of which module
 BigCoreDataStructure came from (it could be aliased to something else
 like "BCDS" in your current namespace for instance.)
 
 But now you have a problem because you have access to BCDS but you
 also want to get at his auxillary non-member functions.    But those
 didn't get imported because they would gum up the namespace.
 
 I'm thinking it would be nice if you could do something like
 ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
 functions in BCDS's module whatever that may be.
 
 I think types do have the information of which module they originated
 in, so technically it should be possible.  Has anyone written a
 routine that can do this?
 
 --bb

Yes. It's in my meta.NameOf module. Which hasn't been updated in quite some time...
Oct 17 2008
parent Don Clugston <nospam nospam.com> writes:
Bill Baxter wrote:
 On Fri, Oct 17, 2008 at 10:18 PM, Don <nospam nospam.com.au> wrote:
 Bill Baxter wrote:
 I find myself sometimes wanting to get an alias to the module
 namespace that a given type came from.

 The reason is this:  these days it's en vogue to make classes contain
 as few functions as necessary, and to write everything else as
 non-member functions.  The problem is that when you are using
 BigCoreDataStructure a lot in your program it's natural to import that
 from other modules and in the end you can lose sight of which module
 BigCoreDataStructure came from (it could be aliased to something else
 like "BCDS" in your current namespace for instance.)

 But now you have a problem because you have access to BCDS but you
 also want to get at his auxillary non-member functions.    But those
 didn't get imported because they would gum up the namespace.

 I'm thinking it would be nice if you could do something like
 ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
 functions in BCDS's module whatever that may be.

 I think types do have the information of which module they originated
 in, so technically it should be possible.  Has anyone written a
 routine that can do this?

 --bb

time...

Neat. Does always give you the true module of definition? Or does it return the module from which the symbol was most immediately imported? For instance if we have this situation: -----OriginalModule.d----- struct TheThing { ... } ----OtherModule.d----- import OriginalModule: SneakyAlias = TheThing; ----FinalModule.d----- import OtherModule : SneakyAlias; moduleOf(SneakyAlias); // does this resolve to OriginalModule or OtherModule? ------------------------------

It gives you OriginalModule. Aliases get resolved.
Oct 18 2008
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:
 I'm thinking it would be nice if you could do something like
 ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
 functions in BCDS's module whatever that may be.

The standard and simple solution to this problem is to import just the name of the module. You can do this with a static import, and you can use an alias to shorten the module name too: static import bc = packagename.modulename; auto x = new bc.SomeClass(...); ... auto y = bc.nonMemberFunction(...); Bye, bearophile
Oct 17 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Sat, 18 Oct 2008 05:58:50 +0900,
Bill Baxter wrote:
 The truly simplest solution here is just to ignore Scott Meyer's
 advice and make nonMemberFunction a static member function.  That way
 if I have access to SomeClass I will always have easy access to
 nonMemberFunction, regardless of whatever round-about chain of imports
 and aliases got me SomeClass.

To define a non-member, *non-friend* function in D you must define it in a different module than the module in which your class is defined. Good- bye encapsulation. :)
Oct 18 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sergey Gromov wrote:
 Sat, 18 Oct 2008 05:58:50 +0900,
 Bill Baxter wrote:
 The truly simplest solution here is just to ignore Scott Meyer's
 advice and make nonMemberFunction a static member function.  That way
 if I have access to SomeClass I will always have easy access to
 nonMemberFunction, regardless of whatever round-about chain of imports
 and aliases got me SomeClass.

To define a non-member, *non-friend* function in D you must define it in a different module than the module in which your class is defined. Good- bye encapsulation. :)

I agree. I'd also agree that file-level encapsulation does make sense. After all, unless fancy code databases are used, the file is the physical unit of protection and change tracking, and it's here to stay. So I don't find one scheme inferior to the other. A possible improvement would be to introduce "module" as a protection level: class A { public: void fun(); // vale tudo module: void gun(); // what private is now protected: void hun(); // zis and derivees package: void iun(); // package-level private: void jun(); // really, really private. I mean it. } I'm not sure how much this improve the state of affairs. I guess it's one of those reddit-ish "Vote up if you want to attract Walter's attention..." Andrei
Oct 18 2008
next sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Sat, 18 Oct 2008 11:52:38 -0500,
Andrei Alexandrescu wrote:
 Sergey Gromov wrote:
 Sat, 18 Oct 2008 05:58:50 +0900,
 Bill Baxter wrote:
 The truly simplest solution here is just to ignore Scott Meyer's
 advice and make nonMemberFunction a static member function.  That way
 if I have access to SomeClass I will always have easy access to
 nonMemberFunction, regardless of whatever round-about chain of imports
 and aliases got me SomeClass.

To define a non-member, *non-friend* function in D you must define it in a different module than the module in which your class is defined. Good- bye encapsulation. :)

I agree. I'd also agree that file-level encapsulation does make sense. After all, unless fancy code databases are used, the file is the physical unit of protection and change tracking, and it's here to stay. So I don't find one scheme inferior to the other.

I'm only saying that if you are to follow Meyers' advice then ModuleOf() won't help you because any "convenience functions" will be defined in another module.
Oct 18 2008
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 Sergey Gromov wrote:
 Sat, 18 Oct 2008 05:58:50 +0900,
 Bill Baxter wrote:
 The truly simplest solution here is just to ignore Scott Meyer's
 advice and make nonMemberFunction a static member function.  That way
 if I have access to SomeClass I will always have easy access to
 nonMemberFunction, regardless of whatever round-about chain of imports
 and aliases got me SomeClass.

To define a non-member, *non-friend* function in D you must define it in a different module than the module in which your class is defined. Good- bye encapsulation. :)

I agree. I'd also agree that file-level encapsulation does make sense. After all, unless fancy code databases are used, the file is the physical unit of protection and change tracking, and it's here to stay. So I don't find one scheme inferior to the other. A possible improvement would be to introduce "module" as a protection level: class A { public: void fun(); // vale tudo module: void gun(); // what private is now protected: void hun(); // zis and derivees package: void iun(); // package-level private: void jun(); // really, really private. I mean it. } I'm not sure how much this improve the state of affairs. I guess it's one of those reddit-ish "Vote up if you want to attract Walter's attention..." Andrei

... Off-topic a bit, but I'd rather to see “package” to be usable between sub-packages (e.g. somelib.feature1.all.d and somelib.feature2.all.d)
Oct 18 2008
prev sibling next sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Fri, Oct 17, 2008 at 10:45 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Bill Baxter:
 I'm thinking it would be nice if you could do something like
 ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
 functions in BCDS's module whatever that may be.

The standard and simple solution to this problem is to import just the name of the module. You can do this with a static import, and you can use an alias to shorten the module name too: static import bc = packagename.modulename; auto x = new bc.SomeClass(...); ... auto y = bc.nonMemberFunction(...);

The truly simplest solution here is just to ignore Scott Meyer's advice and make nonMemberFunction a static member function. That way if I have access to SomeClass I will always have easy access to nonMemberFunction, regardless of whatever round-about chain of imports and aliases got me SomeClass. And that's precisely what I was planning to do here. Then it dawned on me that Scott Meyer's advice would be a lot easier to follow in D if there were a simple way to just get at the enclosing namespace of a type. Another solution would be if I could put some kind static "pointer" to the enclosing namespace inside the type. -- Actually that might work well too ... I think it should be possible to stick "alias foo.bar.TheModule ThisModule;" inside a class. Hmmm. Don's solution is neat, but the fact that it's not built-in would still mean that I'll be in the middle of writing code somewhere and have to stop to add the import for the meta module. And if I wasn't using yet then I need to back up further and actually download Don's module from somewhere etc... --bb
Oct 17 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Fri, Oct 17, 2008 at 10:18 PM, Don <nospam nospam.com.au> wrote:
 Bill Baxter wrote:
 I find myself sometimes wanting to get an alias to the module
 namespace that a given type came from.

 The reason is this:  these days it's en vogue to make classes contain
 as few functions as necessary, and to write everything else as
 non-member functions.  The problem is that when you are using
 BigCoreDataStructure a lot in your program it's natural to import that
 from other modules and in the end you can lose sight of which module
 BigCoreDataStructure came from (it could be aliased to something else
 like "BCDS" in your current namespace for instance.)

 But now you have a problem because you have access to BCDS but you
 also want to get at his auxillary non-member functions.    But those
 didn't get imported because they would gum up the namespace.

 I'm thinking it would be nice if you could do something like
 ModuleOf(BCDS).ANonMemberFuncton to get at one of those non-member
 functions in BCDS's module whatever that may be.

 I think types do have the information of which module they originated
 in, so technically it should be possible.  Has anyone written a
 routine that can do this?

 --bb

Yes. It's in my meta.NameOf module. Which hasn't been updated in quite some time...

Neat. Does always give you the true module of definition? Or does it return the module from which the symbol was most immediately imported? For instance if we have this situation: -----OriginalModule.d----- struct TheThing { ... } ----OtherModule.d----- import OriginalModule: SneakyAlias = TheThing; ----FinalModule.d----- import OtherModule : SneakyAlias; moduleOf(SneakyAlias); // does this resolve to OriginalModule or OtherModule? ------------------------------ --bb
Oct 17 2008