www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Super-private private

reply Arcane Jill <Arcane_member pathlink.com> writes:
I'm sure most of you, having read the manual, will know this already, but I
thought it worth giving it a mention. There is a way, in D, of making something
so super-private, that even code in the same source-file can't see it.

You just do this:

       class A
       {
          class B
          {
              // B stuff
          }

          // A stuff
       }

B is now super-private. Seen from outside the scope of class A {...}, it's just not there. I utilised this trick in implementing my Bool type. It worked a treat. Arcane Jill
Jun 03 2004
next sibling parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Guess I'm missing something obvious, but I cannot find nested classes
documented at all. Even the syntax definition does not contain that
possibility, if I read it correctly ("ClassBodyDeclaration" contains
"Declaration", but I don't see that "Declaration" contains
"ClassDeclaration")


Arcane Jill wrote:

 I'm sure most of you, having read the manual, will know this already, but
 I thought it worth giving it a mention. There is a way, in D, of making
 something so super-private, that even code in the same source-file can't
 see it.
 
 You just do this:
 
       class A
       {
          class B
          {
              // B stuff
          }

          // A stuff
       }

B is now super-private. Seen from outside the scope of class A {...}, it's just not there. I utilised this trick in implementing my Bool type. It worked a treat. Arcane Jill

Jun 03 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <c9nn49$a3m$1 digitaldaemon.com>, Norbert Nemec says...
Guess I'm missing something obvious, but I cannot find nested classes
documented at all. Even the syntax definition does not contain that
possibility, if I read it correctly ("ClassBodyDeclaration" contains
"Declaration", but I don't see that "Declaration" contains
"ClassDeclaration")

I can't remember where I read it, and I can't find it now. I can vaguely remember Walter saying that D has nested classes but not inner classes (or words to that effect). I hope it's a feature and not an accident. If Walter decides it's a bug and fixes it, my code will stop working! But it does work - at least, with the current compiler. Jill
Jun 03 2004
next sibling parent reply EricAnderton at yahoo dot com <EricAnderton_member pathlink.com> writes:
In article <c9noh9$c5v$1 digitaldaemon.com>, Arcane Jill says...
I can't remember where I read it, and I can't find it now. I can vaguely
remember Walter saying that D has nested classes but not inner classes (or words
to that effect).

I remember a posting like that as well. Anyway, it's in black-and-white (red-and-green if you will) on the language comparison chart: http://www.digitalmars.com/d/comparison.html In case anyone is curious about the difference, I found the following (java) article that explains the differences. (I had to satisfy my curiosity on this one, since the exact details of inner and outer classes escaped me.) http://www.javaworld.com/javaworld/javatips/jw-javatip75.html: Nested classes vs. inner classes Nested classes are simply static inner classes. The difference between nested classes and inner classes is the same as the difference between static and nonstatic members of a class: nested classes are associated with the enclosing class itself, whereas inner classes are associated with an object of the enclosing class. Because of this, inner class objects require an object of the enclosing class, while nested class objects do not. Nested classes, therefore, behave just like top-level classes, using the enclosing class to provide a package-like organization. In addition, nested classes have access to all members of the enclosing class.
Jun 03 2004
next sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"EricAnderton at yahoo dot com" <EricAnderton_member pathlink.com> wrote in
message news:c9npn6$e22$1 digitaldaemon.com...
 In article <c9noh9$c5v$1 digitaldaemon.com>, Arcane Jill says...
I can't remember where I read it, and I can't find it now. I can vaguely
remember Walter saying that D has nested classes but not inner classes


to that effect).

I remember a posting like that as well. Anyway, it's in black-and-white (red-and-green if you will) on the language comparison chart: http://www.digitalmars.com/d/comparison.html

It seams natural to me that D has nested classes because i have used them but i'm surprised that they aren't mentioned anywhere!
 In case anyone is curious about the difference, I found the following

 article that explains the differences.  (I had to satisfy my curiosity on

 one, since the exact details of inner and outer classes escaped me.)

I remember those discussions about inner classes, because i thought they would be a good solution to a design problem i was having. The situation was: I had classes(for example) A, B, C, D. And A was on the top, the only class visible from outside of the module, and in it i created instances of B, C, D and i needed access to A from these classes. It seamed to me that passing a reference to A to all B,C and D constructors was a lot of work which inner classes could solve. But eventually i found a rather elegant solution: In the module i declared a global private: A theA; // a reference to object A And then in every public function of A that is accessed from outside of the module i do: theA = this; And then every B,C,D object just uses theA and class A makes sure to set it to the right value. This is in some ways maybe even a better solution than that with inner classes, because with inner classes every inner object will internally have to hold the reference to the enclosing class.
 http://www.javaworld.com/javaworld/javatips/jw-javatip75.html:

 Nested classes vs. inner classes
 Nested classes are simply static inner classes. The difference between

 classes and inner classes is the same as the difference between static and
 nonstatic members of a class: nested classes are associated with the

 class itself, whereas inner classes are associated with an object of the
 enclosing class.

 Because of this, inner class objects require an object of the enclosing

 while nested class objects do not. Nested classes, therefore, behave just

 top-level classes, using the enclosing class to provide a package-like
 organization. In addition, nested classes have access to all members of

 enclosing class.

Jun 03 2004
next sibling parent reply Oskar Linde <d98-oliRE.MO.VE nada.kth.se> writes:
Ivan Senji wrote:
 But eventually i found a rather elegant solution: In the module
 i declared a global private:
 A theA; // a reference to object A
 
 And then in every public function of A that is accessed from outside
 of the module i do:
 theA = this;
 
 And then every B,C,D object just uses theA and class A makes sure
 to set it to the right value.
 
 This is in some ways maybe even a better solution than that with
 inner classes, because with inner classes every inner object
 will internally have to hold the reference to the enclosing class.

This doesn't seem very threadsafe. And if you forget to add theA = this; at any place in A, you will get hidden and hard to find bugs. Seems like adding a reference to the "outer" class is safer in all respects. Or am I wrong? /Oskar
Jun 03 2004
parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"Oskar Linde" <d98-oliRE.MO.VE nada.kth.se> wrote in message
news:c9ob7j$18b2$1 digitaldaemon.com...
 Ivan Senji wrote:
 But eventually i found a rather elegant solution: In the module
 i declared a global private:
 A theA; // a reference to object A

 And then in every public function of A that is accessed from outside
 of the module i do:
 theA = this;

 And then every B,C,D object just uses theA and class A makes sure
 to set it to the right value.

 This is in some ways maybe even a better solution than that with
 inner classes, because with inner classes every inner object
 will internally have to hold the reference to the enclosing class.

This doesn't seem very threadsafe. And if you forget to add theA = this; at any place in A, you will get hidden and hard to find bugs. Seems like adding a reference to the "outer" class is safer in all respects. Or am I wrong?

Threadsafety! I didn't think of that, and you are 100% right! But i think it can be fixed easilly because there aren't many methods from A that can be called from the outside, so i could wrap their code in a synchronized block. Would this help? Adding a reference everywhere is safer, and that is what i initially did. But if you have a class with 3 shorts and create thousands of them, those 4 bytes seamed to much to have for every one.
 /Oskar

Jun 04 2004
prev sibling parent reply EricAnderton at yahoo dot com <EricAnderton_member pathlink.com> writes:
In article <c9ns26$hdl$1 digitaldaemon.com>, Ivan Senji says...
But eventually i found a rather elegant solution: In the module
i declared a global private:
A theA; // a reference to object A

And then in every public function of A that is accessed from outside
of the module i do:
theA = this;

And then every B,C,D object just uses theA and class A makes sure
to set it to the right value.

Hrm.. never would have thought to do that myself, but if it works! :) I wonder if there's a way that templates or mixins could be used to make such a design less tedious to maintain? Just a suggestion: You could also do the same with a static member on the enclosing class (rather than in the module scope), thus further encapsulating the details of this solution. The only problem I can see is, what happens when 'A' needs to be thread-safe? IMO, passing around the formal 'outer' object is the way to go. class Foo{ class Bar{ Foo outer; this(Foo outer){ this.outer = outer; } } Bar aBar; this(){ aBar = new Bar(this); } } ..Which is really nothing special, but at least it works. :) All this aside, I don't think inner classes will be coming to D anytime soon, simply because they're almost not even needed. Take Java for example: 99.9% of the time, your inner class declarations are adaptors passed to satisfy some sort of command or event pattern. D's delegates (for which adaptors are the closest thing in Java) already handle this problem much more elegantly, and succinctly. Plus, when declared as an encolsure, delegates already adopt the parent's scope much like an inner class would. Also, one only needs to into consideration the design consequences of true inner classes to realize the major pitfalls. If you look hard at any given inner class, the high-degree of coupling between the inner and outer spaces should leap out at you as a stumbling block for maintenance. Delegates offer some of the same issues, but impose an atomic solution (representing an edge-case rather than a generalized solution, AOP vs OOP if you will) on the developer which helps keep coupling to a minimum. Now Nested Classes on the other hand let you do some nifty things as well: class MyNamespace{ class Foo{ int a; this(int a){ this.a = a; } void Print(){ printf("a = %d\n",this.a); } } } void main(){ MyNamespace.Foo foo = new MyNamespace.Foo(42); foo.Print(); } ::grin::
Jun 04 2004
parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"EricAnderton at yahoo dot com" <EricAnderton_member pathlink.com> wrote in
message news:c9q2jr$q53$1 digitaldaemon.com...
 In article <c9ns26$hdl$1 digitaldaemon.com>, Ivan Senji says...
But eventually i found a rather elegant solution: In the module
i declared a global private:
A theA; // a reference to object A

And then in every public function of A that is accessed from outside
of the module i do:
theA = this;

And then every B,C,D object just uses theA and class A makes sure
to set it to the right value.

Hrm.. never would have thought to do that myself, but if it works! :) I

 if there's a way that templates or mixins could be used to make such a

 less tedious to maintain?

 Just a suggestion: You could also do the same with a static member on the
 enclosing class (rather than in the module scope), thus further

 the details of this solution.

Good sugestion!
 The only problem I can see is, what happens when 'A' needs to be

 IMO, passing around the formal 'outer' object is the way to go.

Well this is the way i did it at first but changed it so it would use less memory. I have some rellativelly small classes it 4bytes for a reference are too much. I'm thinking how to make it be thread-safe.
 class Foo{
 class Bar{
 Foo outer;
 this(Foo outer){
 this.outer = outer;
 }
 }
 Bar aBar;

 this(){
 aBar = new Bar(this);
 }
 }

 ..Which is really nothing special, but at least it works. :)

 All this aside, I don't think inner classes will be coming to D anytime

 simply because they're almost not even needed.

 Take Java for example: 99.9% of the time, your inner class declarations

 adaptors passed to satisfy some sort of command or event pattern.  D's

 (for which adaptors are the closest thing in Java) already handle this

 much more elegantly, and succinctly.  Plus, when declared as an encolsure,
 delegates already adopt the parent's scope much like an inner class would.

 Also, one only needs to into consideration the design consequences of true

 classes to realize the major pitfalls.  If you look hard at any given

 class, the high-degree of coupling between the inner and outer spaces

 leap out at you as a stumbling block for maintenance.  Delegates offer

 the same issues, but impose an atomic solution (representing an edge-case

 than a generalized solution, AOP vs OOP if you will) on the developer

 helps keep coupling to a minimum.


 Now Nested Classes on the other hand let you do some nifty things as well:

I agree they are very usefull.
 class MyNamespace{
 class Foo{
 int a;
 this(int a){ this.a = a; }
 void Print(){ printf("a = %d\n",this.a); }
 }
 }

 void main(){
 MyNamespace.Foo foo = new MyNamespace.Foo(42);
 foo.Print();
 }

 ::grin::

Jun 04 2004
prev sibling parent Kevin Bealer <Kevin_member pathlink.com> writes:
In article <c9npn6$e22$1 digitaldaemon.com>, EricAnderton at yahoo dot com
says...
In article <c9noh9$c5v$1 digitaldaemon.com>, Arcane Jill says...
I can't remember where I read it, and I can't find it now. I can vaguely
remember Walter saying that D has nested classes but not inner classes (or words
to that effect).

I remember a posting like that as well. Anyway, it's in black-and-white (red-and-green if you will) on the language comparison chart: http://www.digitalmars.com/d/comparison.html In case anyone is curious about the difference, I found the following (java) article that explains the differences. (I had to satisfy my curiosity on this one, since the exact details of inner and outer classes escaped me.) http://www.javaworld.com/javaworld/javatips/jw-javatip75.html: Nested classes vs. inner classes Nested classes are simply static inner classes. The difference between nested classes and inner classes is the same as the difference between static and nonstatic members of a class: nested classes are associated with the enclosing class itself, whereas inner classes are associated with an object of the enclosing class. Because of this, inner class objects require an object of the enclosing class, while nested class objects do not. Nested classes, therefore, behave just like top-level classes, using the enclosing class to provide a package-like organization. In addition, nested classes have access to all members of the enclosing class.

In the last sentence, you mean "inner classes have access...", since you would have to be associated with an outer object to find those members, right? Kevin
Jun 03 2004
prev sibling parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Arcane Jill wrote:

 In article <c9nn49$a3m$1 digitaldaemon.com>, Norbert Nemec says...
Guess I'm missing something obvious, but I cannot find nested classes
documented at all. Even the syntax definition does not contain that
possibility, if I read it correctly ("ClassBodyDeclaration" contains
"Declaration", but I don't see that "Declaration" contains
"ClassDeclaration")

I can't remember where I read it, and I can't find it now. I can vaguely remember Walter saying that D has nested classes but not inner classes (or words to that effect). I hope it's a feature and not an accident. If Walter decides it's a bug and fixes it, my code will stop working!

I'm pretty sure that nested classes are a feature, but the question of privacy that you raised with your original post is absolutely unclear to me. That's why I took at look at the specs: I don't see any reason why your example should give any effect of "super-private private" as you call it.
Jun 03 2004
prev sibling parent Ant <Ant_member pathlink.com> writes:
In article <c9mjfa$1nlr$1 digitaldaemon.com>, Arcane Jill says...
I'm sure most of you, having read the manual, will know this already, but I
thought it worth giving it a mention. There is a way, in D, of making something
so super-private, that even code in the same source-file can't see it.

You just do this:

       class A
       {
          class B
          {
              // B stuff
          }

          // A stuff
       }

B is now super-private. Seen from outside the scope of class A {...}, it's just not there. I utilised this trick in implementing my Bool type. It worked a treat. Arcane Jill

(probably I'm just raising another non-issue :p ) Walter!, people are already using constructs for a purpouse other then the intendend by the language! Many times that shows the strenghs of the concepts. Here I think it's showing some kind of limitation... Why is there a necessity to do this in an indirect way? How can it be corrected? Ant
Jun 03 2004