October 30, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Neia Neutuladh | On Tuesday, 30 October 2018 at 15:12:50 UTC, Neia Neutuladh wrote:
> On Tue, 30 Oct 2018 06:44:10 +0000, unprotected-entity wrote:
>> [...]
>
> I just pointed out ways in which they don't work the same. Let's add in some code to help out:
>
> C++:
> ---
> class C
> {
> private int i;
> friend void foo();
> };
> void foo()
> {
> C c;
> c.i = 10;
> }
> ---
>
> Java and C# do not have a way to declare friends.
>
> Also C++:
> ---
> class C {
> class CA {
> void foo() {
> CB b;
> // access error
> b.j++;
> C c;
> // works fine
> c.i++;
> }
> };
> class CB {
> private: int j;
> };
> private: int i;
> };
> ---
>
> In C++, you can access private variables in your containing class (and its retaining class recursively), but not in other classes it contains.
>
> Java:
> ---
> public class C {
> private int i;
> public class Nested {
> private int j;
> }
> public class Nested2 {
> public void foo(Nested n, C c) {
> n.j++;
> c.i++;
> }
> }
> }
> ---
>
> In Java, protections apply to the outermost nested class. You can access anything that any enclosing or nested class can access.
>
> C# doesn't let you do any of this. In C#, you can make something private to a DLL, or you can make it private to exactly one type (and none of its nested types or parent types).
>
>> [...]
>
> You didn't include a link.
>
>> [...]
>
> Again, C++, C#, and Java all do different things with protection attributes, so saying you want something that satisfies people's expectations when they're coming from C++, C#, or Java doesn't give an actual objective.
>
> I also did a survey of like 14 different programming languages to see what they did, and there is very little consistency. So why do you want C++, C#, and Java users to have an easier time with D's protection attributes instead of people coming from some other set of languages?
>
>> [...]
>
> Aside from using more modules.
>
>> [...]
>
> If you want people to change how they communicate with you, it might benefit you to consider how to accomplish that. Trying to call someone an asshole on the sly doesn't seem like an effective way to improve their attitudes toward you.
He's talking about private in general meaning that something is accessible within the scope it's declared in. Which "in general" is what private means, obviously some languages have caveats, and some languages behave differently. C++, C#, Swift, and Java, Kotlin, all use private in a class to mean "this variable is only accessible from the scope of this class" where the definition of scope varies (as you have pointed out) between languages. And that is quite consistent. Rust doesn't have a keyword called private AFAIK.
Cheers,
- Ali
|
October 31, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ShadoLight | On Tuesday, 30 October 2018 at 09:43:54 UTC, ShadoLight wrote:
> At this point this threat are really arguing about a personal preferences; it is not a black or white affair.
Yes, true, sort of.
The problem as I see it, is that D does not even give you (me) the option to implement such my preference - which is to declare a private member of a class within a module, and have the guarantee (by the compiler) that other code my module does not directly touch it. It's not a big ask really. It's what I already have in C++, Java and C#.
It doesn't mean changing what private means.
But it could, rather easily, mean adding some syntax that would allow me to clearly declare my intentions (such as: strict private - as freepascal do it ( I made a post about this, but my posts are not being put up for some reason - maybe the person who does that thing is asleep or whatever.
I can't have a conversation under those conditions (i.e. where some person, somewhere, at some random time, decides whether posts should be displayed - if they get around to it that is..), so I'm not going to bother wasting any more time with this matter. I just got new xbox one x, and rdr2 - so I'm attention will be elsewhere, for some time .....
|
October 31, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Monday, 29 October 2018 at 10:32:00 UTC, Mike Parker wrote: > > I can't speak for others, but it's a feature I use fairly often. I tend to design aggregates and free functions to the module, as a cohesive whole, rather than as separate parts. If I want separate parts, I put them in different modules and use `package` for the bits that need to stay out of the public API. Works a treat. Well, I think I've dicussed this enough. I point you all to this link, that has essentially what I'm asking for in D. "'www.freepascal.org/docs-html/ref/refse34.html'" Something like their 'strict private' would really be an advantage to D. And.. not a single response, so far, has reasonably demonstated, that giving this option to the programmer, would negatively affect the perception or use of D. I rest my case. |
October 31, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On Sunday, 28 October 2018 at 15:47:15 UTC, Stanislav Blinov wrote:
> On Sunday, 28 October 2018 at 15:41:47 UTC, Neia Neutuladh wrote:
>
>> In D, x is private to C and any types or functions defined in the same module.
>
> ...and can be accessed via reflection (.tupleof). </Pedantry>
Whenver that statement comes up, it needs to be mentioned, yet again, that access modifiers are not a 'security' feature.
They "are a convenient design constraint, to help us structure our applications properly." - and yes, they are convenient within a module too (unless your module doesn't care about them - cause then they're completely useless).
Using reflection to explicitly break open something, is not the same as leaving it completely open in the first place (within a module, where that is always the case).
|
October 31, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
> Just how often does one need to access the private members of a class, within a module?
a lot actually. e.g. unittests
|
November 01, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zot | On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
> On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
>> Just how often does one need to access the private members of a class, within a module?
>
> a lot actually. e.g. unittests
that does not compute.
all you are doing is further coupling unit-tests, with all the other crap that is already coupled in your module.
Too many programmers these days, have no concept of clean architecture.
You should be find ways to further decouple your code, not finding even more ways to further couple it.
Since, in D, there is no concept of encapsulation, or information hiding, *within* a module, it (sadly) promotes the wrong type of architecture, by default. The module is just a convenient hack to avoid thinking about decoupling. Everything could dependent on everything else in your module - you have to read the whole 10,000 lines to discover what it's all about..(that's how much of phobos is designed, it seems).
It's C like programming, masquerading as modern software design.
if you want to test something that is private, call its public interface. that seems a pretty sensible guideline to me.
and why is it so hard to put the unit test inside the actual class?
that too seems like a pretty sensible guidline, to me.
many on this forum have said, that the amount of code in your module should be fairly minimal (especially if you take the one class per module concept seriously).
of course, in practice, that is not what happens - just look at phobos.
the module should be a grouping of related functionality. that doesn't mean it should have no concept of encapsulation of information hiding within it - that will only lead to bad design.
---------------
module test;
class Test
{
private int Value;
unittest
{
Test t = new Test();
assert(t.Value == 10);
}
}
----------------
|
November 01, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | On Thu, 01 Nov 2018 02:44:47 +0000, unprotected-entity wrote: > On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote: >> On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote: >>> Just how often does one need to access the private members of a class, within a module? >> >> a lot actually. e.g. unittests > > that does not compute. > > all you are doing is further coupling unit-tests, with all the other crap that is already coupled in your module. If I'm writing larger-scale tests, I want them to be durable to code changes; those tests are about exercising the code in the same way as a consumer of my library would. The types of tests I'm writing that might need access to private members are generally pretty short and focused, and they don't test the library as I expect consumers to use it. They're likely to be testing a private function opaquely, not examining private variables in a class. And if I change the function, I probably need to change the tests. > and why is it so hard to put the unit test inside the actual class? class Foo(T) { unittest {} } That test might never get run with `dub test`, and it's going to get compiled into every instantiation of the type in every consumer of my library. That's kinda bad. There *is* a workaround. Where you would write: class Foo(T) { } unittest { new Foo!int; } You instead write: class Foo(T) { version (MyLibraryTest) static if (is(T == int)) unittest { new Foo; } } version (MyLibraryTest) unittest { // force the template to instantiate Foo!int f; } That's a lot easier to mess up, so I'd rather use the short version. |
November 01, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to unprotected-entity | On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity wrote: > On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis wrote: >> > It's not (just) that I don't like it, it's that I don't like not giving the programmer the tool to better encapsulate their code (specifically classes) *within* a module. You don't need to protect code in your module from other code in your module. If you do, put them in different modules. > In D however, it's exactly how you're meant to do it - it's by design - it's reaching out and saying, this is how you should do it. It _is_ how you should do it, but not with giant modules. Just have smaller modules. > D seems to be proud, that you cannot encapsulate a class, within a module, from other code also in that module. If C++/C#/Java took that view, imagine the outcry. Java doesn't compare - every class is in its own file. If you want to write D code Java style, and have `private` work the same way, then have a class per module. As for C++, one could argue that it encourages the practice of having source files implement multiple classes, which is part of the reason anyone uses `friend` there anyway! > And given what I've seen in phobos..well... I'm still looking for the 'design'. There are parts of Phobos that aren't very well designed, especially the older code. There are also parts that are great (std.experimental.allocator for instance). > All I see are gigantic modules full of code...that does who knows what to each other..cause they're all friends and can do whatever they like to each other, in D. Yeah, that's not good. But the barrier to change the standard library is higher so I'm mostly ok with that. |
November 01, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bastiaan Veelo | On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
> On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity wrote:
>> On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:
>>>
>>> I hear you and understand you, but personally I still prefer the D spec as it is in this regard, except for the confusing aspect that you shouldn’t `alias this` a private member; but that is rather a limitation of alias, not of encapsulation.
>>>
>>
>> If your were sitting on a plane that was running the following D code, you might think differently ;-)
>>
>> --------
>> class Plane
>> {
>> private static int MAX_SPEED = 1000;
>>
>> public void change_max_speed(int speed)
>> {
>> if(speed >= 1000)
>> MAX_SPEED = speed;
>> }
>>
>> }
>>
>> immutable Plane p = new Plane();
>>
>> // god no! why aren't you using the public interface of the class for this!
>> void SetMaxSpeed() { p.MAX_SPEED = -1; }
>>
>> void Bar() { SetMaxSpeed(); } // mmm...trouble is about to begin...
>>
>> void main()
>> {
>> import std.stdio;
>>
>> Bar(); // oohps. thanks D module. we're all going to die!
>>
>> // by the time you see this, it's too late for you, and your passengers.
>> writeln(p.MAX_SPEED);
>>
>> };
>>
>>
>> -------
>
> :-) Why is MAX_SPEED mutable or even a runtime value, let alone signed?
Strictly my opinion below, but I believe wholeheartedly in this:
Using unsigned integers for anything except bit patterns and talking to hardware is an open invitation to bugs. The C++ community has recognised this and admitted that using size_t everywhere in the STL was a mistake.
"Ah, but I want type safety!". Uh-huh:
-----------------
int[] ints;
// indexing uses size_t, but...
auto i = ints[-1]; // look ma, no errors or warnings!
-----------------
The problem in D and C++ is that they inherit behaviour from C, and in this case the important part of that inheritance is that integers of different types convert implicitly to each other. There is *no* type-safety when using unsigned integers. And because bit-patterns and actual integers share the same type now, people will invariably do something "they're not supposed to" and perform arithmetic with these values and usually wrap around. It's not pretty and it's not fun to debug.
I have literally lost count of how many bugs I've had to fix due to unsigned integers. `long` is large enough for anything you need, as Java has shown for 2 decades now.
Friends don't let friends use unsigned types for counting.
|
November 01, 2018 Re: Why do private member variables behaved like protected in the same module when creating deriving class? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zot | On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
> On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
>> Just how often does one need to access the private members of a class, within a module?
>
> a lot actually. e.g. unittests
Unit tests should go through the public interface like anyone else. All private members and functions are implementation details that shouldn't matter and shouldn't break any tests if they're all removed.
|
Copyright © 1999-2021 by the D Language Foundation