View mode: basic / threaded / horizontal-split · Log in · Help
October 17, 2008
Getting module of a class
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
October 17, 2008
Re: Getting module of a class
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...
October 17, 2008
Re: Getting module of a class
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
October 17, 2008
Re: Getting module of a class
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
October 17, 2008
Re: Getting module of a class
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
October 18, 2008
Re: Getting module of a class
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
>> 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?
> ------------------------------

It gives you OriginalModule. Aliases get resolved.
October 18, 2008
Re: Getting module of a class
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.  :)
October 18, 2008
Re: Getting module of a class
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
October 18, 2008
Re: Getting module of a class
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.
October 18, 2008
Re: Getting module of a class
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)
Top | Discussion index | About this forum | D home