www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Small troubles with "private"

reply "bearophile" <bearophileHUGS lycos.com> writes:
1) I usually write more than one class or struct inside each D 
module, unlike in Java. But sometimes when I move that class or 
struct elsewhere (during refactoring, or in other situations) I 
get access errors to private fields. Those errors were already in 
my code, but I didn't see them because "private" in D means 
module-private.

2) My unittests are useful to catch bugs when I run them at 
run-time, but they are also use to exercise code, this means to 
actually use it, and catch some bugs statically (instantiating 
templates, etc). But unfortunately such unittests can't catch 
protection bugs because most of my unittests are inside the same 
module, so "private" gets ignored.

3) A third problem with module-private is that newbies coming 
from Python, C, and other languages that don't have 
private/protected attributes and write little experimental D 
programs, have less chances to _learn_ the true semantics of the 
privacy attributes until they start to spread their classes in 
different modules.

How to solve such little troubles? A possible idea is to add to D 
another attribute, a kind of "private private" that is enforced 
inside the same module. It could be named "super private" because 
D has the "super" keyword :-) But this idea doesn't solve all the 
problems, because sometimes you don't want to use a super private 
attribute.

Bye,
bearophile
Nov 05 2013
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Tuesday, 5 November 2013 at 16:00:43 UTC, bearophile wrote:
 1) I usually write more than one class or struct inside each D 
 module, unlike in Java. But sometimes when I move that class or 
 struct elsewhere (during refactoring, or in other situations) I 
 get access errors to private fields. Those errors were already 
 in my code, but I didn't see them because "private" in D means 
 module-private.
Would the package access specifier work for this, as long as you keep it in the same package? http://dlang.org/attribute.html#ProtectionAttribute
 2) My unittests are useful to catch bugs when I run them at 
 run-time, but they are also use to exercise code, this means to 
 actually use it, and catch some bugs statically (instantiating 
 templates, etc). But unfortunately such unittests can't catch 
 protection bugs because most of my unittests are inside the 
 same module, so "private" gets ignored.
I've seen Jacob Carlborg suggest that unittests should be put in a separate module before, maybe this is an argument for that, even in smaller projects.
 3) A third problem with module-private is that newbies coming 
 from Python, C, and other languages that don't have 
 private/protected attributes and write little experimental D 
 programs, have less chances to _learn_ the true semantics of 
 the privacy attributes until they start to spread their classes 
 in different modules.
I think this would be confusing for people coming from Java, C#, and C++ as well, but I think it's just something you have to learn when using D. I think that even if they don't know about it, they'll come across it pretty quickly.
 How to solve such little troubles? A possible idea is to add to 
 D another attribute, a kind of "private private" that is 
 enforced inside the same module. It could be named "super 
 private" because D has the "super" keyword :-) But this idea 
 doesn't solve all the problems, because sometimes you don't 
 want to use a super private attribute.
I think this might add too much complication for the small benefit. Programmers would have to consider yet another access specifier when adding struct/class variables. It seems like unnecessary mental overhead for something that can be avoided fairly easily.
Nov 05 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Meta:

 Would the package access specifier work for this, as long as 
 you keep it in the same package?
It's the opposite problem, I'd like to detect where I am using private names by mistake, and the compiler doesn't complain because it's in the same module.
 I've seen Jacob Carlborg suggest that unittests should be put 
 in a separate module before, maybe this is an argument for 
 that, even in smaller projects.
Putting the unittests very close to their functions/methods is very good, for various reasons. I even sometimes write functions like this: void foo() { ... } unittest { ... }
 I think this would be confusing for people coming from Java, 
 C#, and C++ as well,
People coming from Java/C# are able to learn it well, but newbies that don't know about private attributes will have troubles, because to learn something new you usually prefer/need a strict teacher (or strict compiler).
 Programmers would have to consider yet another access specifier 
 when adding struct/class variables. It seems like unnecessary 
 mental overhead for something that can be avoided fairly easily.
In the main D newsgroup some people were recently discussing about a new access specifier, to be used by reference data "owned" by a class/struct :-) Bye, bearophile
Nov 05 2013
next sibling parent =?UTF-8?B?U2ltZW4gS2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On 05.11.2013 17:40, bearophile wrote:
 Meta:

 I've seen Jacob Carlborg suggest that unittests should be put in a
 separate module before, maybe this is an argument for that, even in
 smaller projects.
Putting the unittests very close to their functions/methods is very good, for various reasons. I even sometimes write functions like this: void foo() { ... } unittest { ... }
I routinely do both in my code - test functionality in the same module, and the interface in a separate module. Also, I love writing unittests the way you mention here - I've gotten used to thinking something's wrong if there's not a unittest block immediately following a function. It looks nice, and meshes nicely with DBC: auto foo(Args args) in { } out { } body { } unittest { } -- Simen
Nov 05 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-11-05 17:40, bearophile wrote:

 void foo() {
      ...
 } unittest {
      ...
 }
As soon as you want to do something more advanced than plain unit tests that doesn't scale very well. Even doing unit tests it's harder to take advantage of setting up before and after callbacks that are shared between many tests. -- /Jacob Carlborg
Nov 05 2013
prev sibling next sibling parent reply "Gary Willoughby" <dev nomad.so> writes:
On Tuesday, 5 November 2013 at 16:00:43 UTC, bearophile wrote:
 1) I usually write more than one class or struct inside each D 
 module, unlike in Java. But sometimes when I move that class or 
 struct elsewhere (during refactoring, or in other situations) I 
 get access errors to private fields. Those errors were already 
 in my code, but I didn't see them because "private" in D means 
 module-private.

 2) My unittests are useful to catch bugs when I run them at 
 run-time, but they are also use to exercise code, this means to 
 actually use it, and catch some bugs statically (instantiating 
 templates, etc). But unfortunately such unittests can't catch 
 protection bugs because most of my unittests are inside the 
 same module, so "private" gets ignored.

 3) A third problem with module-private is that newbies coming 
 from Python, C, and other languages that don't have 
 private/protected attributes and write little experimental D 
 programs, have less chances to _learn_ the true semantics of 
 the privacy attributes until they start to spread their classes 
 in different modules.

 How to solve such little troubles? A possible idea is to add to 
 D another attribute, a kind of "private private" that is 
 enforced inside the same module. It could be named "super 
 private" because D has the "super" keyword :-) But this idea 
 doesn't solve all the problems, because sometimes you don't 
 want to use a super private attribute.

 Bye,
 bearophile
IMHO private should mean private as enforced by other languages and use another keyword for module level privacy. 'internal' springs to mind.
Nov 05 2013
next sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Tuesday, 5 November 2013 at 16:59:09 UTC, Gary Willoughby
wrote:
 IMHO private should mean private as enforced by other languages 
 and use another keyword for module level privacy. 'internal' 
 springs to mind.
This will of course cause breakage! :/
Nov 05 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-11-05 17:59, Gary Willoughby wrote:

 IMHO private should mean private as enforced by other languages and use
 another keyword for module level privacy. 'internal' springs to mind.
Which other languages? "private" in Ruby and Java is not the same. -- /Jacob Carlborg
Nov 05 2013
next sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Wednesday, 6 November 2013 at 07:46:00 UTC, Jacob Carlborg 
wrote:
 Which other languages? "private" in Ruby and Java is not the 
 same.
The one's which implement private as meaning accessible to the class only.
Nov 06 2013
prev sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Wednesday, 6 November 2013 at 07:46:00 UTC, Jacob Carlborg
wrote:
 Which other languages? "private" in Ruby and Java is not the 
 same.
The one's which implement private as meaning accessible to the class only.
Nov 06 2013
prev sibling next sibling parent reply John J <john.joyus gmail.com> writes:
On 11/05/2013 11:00 AM, bearophile wrote:
 How to solve such little troubles? A possible idea is to add to D
 another attribute, a kind of "private private" that is enforced inside
 the same module. It could be named "super private" because D has the
 "super" keyword :-) But this idea doesn't solve all the problems,
 because sometimes you don't want to use a super private attribute.
How about "strict private"
Nov 05 2013
parent "Meta" <jared771 gmail.com> writes:
On Tuesday, 5 November 2013 at 21:01:40 UTC, John J wrote:
 On 11/05/2013 11:00 AM, bearophile wrote:
 How to solve such little troubles? A possible idea is to add 
 to D
 another attribute, a kind of "private private" that is 
 enforced inside
 the same module. It could be named "super private" because D 
 has the
 "super" keyword :-) But this idea doesn't solve all the 
 problems,
 because sometimes you don't want to use a super private 
 attribute.
How about "strict private"
I think "static private" is the best option (just kidding).
Nov 06 2013
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 05 Nov 2013 16:00:41 -0000, bearophile <bearophileHUGS lycos.com>  
wrote:

 1) I usually write more than one class or struct inside each D module,  
 unlike in Java. But sometimes when I move that class or struct elsewhere  
 (during refactoring, or in other situations) I get access errors to  
 private fields. Those errors were already in my code, but I didn't see  
 them because "private" in D means module-private.

 2) My unittests are useful to catch bugs when I run them at run-time,  
 but they are also use to exercise code, this means to actually use it,  
 and catch some bugs statically (instantiating templates, etc). But  
 unfortunately such unittests can't catch protection bugs because most of  
 my unittests are inside the same module, so "private" gets ignored.

 3) A third problem with module-private is that newbies coming from  
 Python, C, and other languages that don't have private/protected  
 attributes and write little experimental D programs, have less chances  
 to _learn_ the true semantics of the privacy attributes until they start  
 to spread their classes in different modules.

 How to solve such little troubles? A possible idea is to add to D  
 another attribute, a kind of "private private" that is enforced inside  
 the same module. It could be named "super private" because D has the  
 "super" keyword :-) But this idea doesn't solve all the problems,  
 because sometimes you don't want to use a super private attribute.
I think a compiler flag is the best option. The flag would cause warnings to appear for each "violation" of strict privacy between classes in the same module. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 06 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11/05/2013 05:00 PM, bearophile wrote:
 1) I usually write more than one class or struct inside each D module,
 unlike in Java. But sometimes when I move that class or struct elsewhere
 (during refactoring, or in other situations) I get access errors to
 private fields. Those errors were already in my code, but I didn't see
 them because "private" in D means module-private.

 2) My unittests are useful to catch bugs when I run them at run-time,
 but they are also use to exercise code, this means to actually use it,
 and catch some bugs statically (instantiating templates, etc). But
 unfortunately such unittests can't catch protection bugs because most of
 my unittests are inside the same module, so "private" gets ignored.

 3) A third problem with module-private is that newbies coming from
 Python, C, and other languages that don't have private/protected
 attributes and write little experimental D programs, have less chances
 to _learn_ the true semantics of the privacy attributes until they start
 to spread their classes in different modules.

 How to solve such little troubles? A possible idea is to add to D
 another attribute, a kind of "private private" that is enforced inside
 the same module. It could be named "super private" because D has the
 "super" keyword :-) But this idea doesn't solve all the problems,
 because sometimes you don't want to use a super private attribute.

 Bye,
 bearophile
How about just adding full granularity? By condition: visibleIf!true // public visibleIf!(isSubtypeOf!(typeof(this))) // protected By explicit enumeration: visible!(getModule!(typeof(this))) // private visible!(typeof(this), T) // visible to type 'T' visible!(typeof(this)) // 'super private' visible!foo // only (member) function 'foo' can access it visible!() // nobody can access it
Nov 06 2013
parent "Chris Cain" <clcain uncg.edu> writes:
On Wednesday, 6 November 2013 at 12:19:26 UTC, Timon Gehr wrote:
 How about just adding full granularity?

 By condition:

  visibleIf!true                         // public
  visibleIf!(isSubtypeOf!(typeof(this))) // protected

 By explicit enumeration:

  visible!(getModule!(typeof(this))) // private
  visible!(typeof(this), T) // visible to type 'T'
  visible!(typeof(this)) // 'super private'
  visible!foo // only (member) function 'foo' can access it
  visible!() // nobody can access it
Dear Santa, ...
Nov 06 2013
prev sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Tuesday, 5 November 2013 at 16:00:43 UTC, bearophile wrote:
 How to solve such little troubles? A possible idea is to add to 
 D another attribute, a kind of "private private" that is 
 enforced inside the same module. It could be named "super 
 private" because D has the "super" keyword :-) But this idea 
 doesn't solve all the problems, because sometimes you don't 
 want to use a super private attribute.

 Bye,
 bearophile
I don't think such problems are valuable to solve.
Nov 07 2013