www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - private mixin function

reply Frank Benoit <benoit__ __tionex.de> writes:
I want to make a mixin for a private function.

--------------------------------------------------------------------------

template m(T){
	private void func(){}
}

class C{
	mixin m!(byte) m1;
	public this(){
		func(); // error: func is private
	}
}

--------------------------------------------------------------------------

Is this possible ?
Apr 11 2006
parent reply Frank Benoit <benoit__ __tionex.de> writes:
Never mind. Calling it with
m1.func();
works.
Apr 11 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Frank Benoit" <benoit__ __tionex.de> wrote in message 
news:e1gh7m$2btt$1 digitaldaemon.com...
 Never mind. Calling it with
 m1.func();
 works.

Hahaha, it's two bugs canceling each other out (maybe). If the template is defined in the same module as C, I would imagine C should be able to access its private members (though that might be some other rule); but at the same time, if you use the fully qualified name of something, protection attributes mean nothing (hence why calling m1.func() works).
Apr 11 2006
next sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Jarrett Billingsley wrote:
 "Frank Benoit" <benoit__ __tionex.de> wrote in message 
 news:e1gh7m$2btt$1 digitaldaemon.com...
 Never mind. Calling it with
 m1.func();
 works.

Hahaha, it's two bugs canceling each other out (maybe). If the template is defined in the same module as C, I would imagine C should be able to access its private members (though that might be some other rule); but at the same time, if you use the fully qualified name of something, protection attributes mean nothing (hence why calling m1.func() works).

-- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 12 2006
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 11 Apr 2006 16:03:36 -0400, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:
 "Frank Benoit" <benoit__ __tionex.de> wrote in message
 news:e1gh7m$2btt$1 digitaldaemon.com...
 Never mind. Calling it with
 m1.func();
 works.

Hahaha, it's two bugs canceling each other out (maybe).

I have a feeling it's related. I think mixins have some problems which should be addressed, or at the very least cleared up in the docs. Let me elaborate... :) In this case a 'MixinIdentifier' has been given 'm1': mixin m!(byte) m1; The docs say: "If a mixin has a MixinIdentifier, it can be used to disambiguate" which, isn't exactly what we're using it for, but it does seem to solve the problem. Then again, maybe this is the same bug as you mention where a private member in another module can be accessed with it's full name. I think part of the problem is that "A mixin has its own scope ...", this was taken a little out of context, see: http://www.digitalmars.com/d/mixin.html It suggests to me that mixin has a scope (especially when you give it an identifier like 'm1'). If it has a scope, and that scope is m1, then it makes sense that need to call the function with m1.func(); That said, earlier in the docs it says "The declarations in a mixin are 'imported' into the surrounding scope" and "It is analogous to cutting and pasting the body of the template into the location of the mixin", if those statements were true then this code should work: template m(T){ private void func() {} } class C{ mixin m!(byte); public this(){ func(); // error: func is private } } (note, no identifier) but it doesn't. It gives the same error as you had before. As there is no mixin identifier there is no solution here. I've had this exact problem with them in the past, trying to mix private declarations into a class just plain doesn't work. Instead it results in something akin to a derived class, where the base had private members. They're just plain inaccessable, as you've found. I would love to see this cleaned up. Regan
Apr 12 2006
next sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Regan Heath wrote:
...

Oops. I've only noticed this now, and so the bug report that I made about this was "non-whole", as it only contemplated private constructors, and not any entity/symbol. It is corrected now: http://d.puremagic.com/bugzilla/show_bug.cgi?id=49 -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 12 2006
prev sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Regan Heath wrote:
 On Tue, 11 Apr 2006 16:03:36 -0400, Jarrett Billingsley  
 <kb3ctd2 yahoo.com> wrote:
 
 "Frank Benoit" <benoit__ __tionex.de> wrote in message
 news:e1gh7m$2btt$1 digitaldaemon.com...

 Never mind. Calling it with
 m1.func();
 works.

Hahaha, it's two bugs canceling each other out (maybe).

I have a feeling it's related. I think mixins have some problems which should be addressed, or at the very least cleared up in the docs. Let me elaborate... :) In this case a 'MixinIdentifier' has been given 'm1': mixin m!(byte) m1; The docs say: "If a mixin has a MixinIdentifier, it can be used to disambiguate" which, isn't exactly what we're using it for, but it does seem to solve the problem. Then again, maybe this is the same bug as you mention where a private member in another module can be accessed with it's full name. I think part of the problem is that "A mixin has its own scope ...", this was taken a little out of context, see: http://www.digitalmars.com/d/mixin.html It suggests to me that mixin has a scope (especially when you give it an identifier like 'm1'). If it has a scope, and that scope is m1, then it makes sense that need to call the function with m1.func(); That said, earlier in the docs it says "The declarations in a mixin are 'imported' into the surrounding scope" and "It is analogous to cutting and pasting the body of the template into the location of the mixin", if those statements were true then this code should work: template m(T){ private void func() {} } class C{ mixin m!(byte); public this(){ func(); // error: func is private } } (note, no identifier) but it doesn't. It gives the same error as you had before. As there is no mixin identifier there is no solution here. I've had this exact problem with them in the past, trying to mix private declarations into a class just plain doesn't work. Instead it results in something akin to a derived class, where the base had private members. They're just plain inaccessable, as you've found. I would love to see this cleaned up. Regan

This might seem crazy, but bear with me. It looks to me like the function is declared as private In-Terms-Of the mixin, rather than the instantiating class, therefore maybe the solution would be to be able to do this: # template m (T) { # void func () {} # } # # class C { # private mixin m!(byte); # # public this () { # func(); # } # } Note that the 'private' attribute is moved out of the template, and instead applied to the mixin statement itself. I suppose the meaning ought to be something similar to the meaning of public/protected/private in inheritance (iow, similar to the way "class Foo : private Bar" would behave). -- Chris Nicholson-Sauls
Apr 12 2006
parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 12 Apr 2006 11:44:56 -0500, Chris Nicholson-Sauls  
<ibisbasenji gmail.com> wrote:
 Regan Heath wrote:
 On Tue, 11 Apr 2006 16:03:36 -0400, Jarrett Billingsley   
 <kb3ctd2 yahoo.com> wrote:

 "Frank Benoit" <benoit__ __tionex.de> wrote in message
 news:e1gh7m$2btt$1 digitaldaemon.com...

 Never mind. Calling it with
 m1.func();
 works.

Hahaha, it's two bugs canceling each other out (maybe).

which should be addressed, or at the very least cleared up in the docs. Let me elaborate... :) In this case a 'MixinIdentifier' has been given 'm1': mixin m!(byte) m1; The docs say: "If a mixin has a MixinIdentifier, it can be used to disambiguate" which, isn't exactly what we're using it for, but it does seem to solve the problem. Then again, maybe this is the same bug as you mention where a private member in another module can be accessed with it's full name. I think part of the problem is that "A mixin has its own scope ...", this was taken a little out of context, see: http://www.digitalmars.com/d/mixin.html It suggests to me that mixin has a scope (especially when you give it an identifier like 'm1'). If it has a scope, and that scope is m1, then it makes sense that need to call the function with m1.func(); That said, earlier in the docs it says "The declarations in a mixin are 'imported' into the surrounding scope" and "It is analogous to cutting and pasting the body of the template into the location of the mixin", if those statements were true then this code should work: template m(T){ private void func() {} } class C{ mixin m!(byte); public this(){ func(); // error: func is private } } (note, no identifier) but it doesn't. It gives the same error as you had before. As there is no mixin identifier there is no solution here. I've had this exact problem with them in the past, trying to mix private declarations into a class just plain doesn't work. Instead it results in something akin to a derived class, where the base had private members. They're just plain inaccessable, as you've found. I would love to see this cleaned up. Regan

This might seem crazy, but bear with me. It looks to me like the function is declared as private In-Terms-Of the mixin, rather than the instantiating class

Yes, that's exactly what I was suggesting by saying the result was akin to a derived class, eg: class A { //AKA the mixin private void func() {} } (in a different module) class B : A { this() { func(); //error, private } }
 , therefore maybe the solution would be to be able to do this:

 # template m (T) {
 #   void func () {}
 # }
 #
 # class C {
 #   private mixin m!(byte);
 #
 #   public this () {
 #     func();
 #   }
 # }

 Note that the 'private' attribute is moved out of the template, and  
 instead applied to the mixin statement itself.  I suppose the meaning  
 ought to be something similar to the meaning of public/protected/private  
 in inheritance (iow, similar to the way "class Foo : private Bar" would  
 behave).

Only it doesn't let you go: template m(T) { private void func(); public void foo(); } class B { mixin m!(byte); } and have 'func' private in B, and 'foo' public in B. Instead you have to make several templates and mix them all seperately. Regan
Apr 12 2006