Thread overview
private mixin function
Apr 11, 2006
Frank Benoit
Apr 11, 2006
Frank Benoit
Apr 12, 2006
Bruno Medeiros
Apr 12, 2006
Regan Heath
Apr 12, 2006
Bruno Medeiros
Apr 12, 2006
Regan Heath
April 11, 2006
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 ?
April 11, 2006
Never mind. Calling it with
m1.func();
works.
April 11, 2006
"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).


April 12, 2006
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). 
> 
> 
Indeed!

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
April 12, 2006
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
April 12, 2006
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
April 12, 2006
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
April 12, 2006
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).
>>   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

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