On Friday, 3 June 2022 at 05:34:48 UTC, forkit wrote:
>That only option available to me in D, to ensure that my class has truly 'private' members (so that no other code within the same module can access them), is to put it in it's own module.
That's so sad.
No, it's not sad. Just, please consider this:
struct Foo {
private int _x;
void x(int val) { _x = val; }
}
vs. this:
struct Foo {
private int _x;
}
void x(Foo f} { f._x = x; }
The only difference here is that in one case, the function manipulating _x
is above the brace that terminates Foo
, and in the other case it's below it. In practical terms, the person editing the module has access to the function in both cases.
You can argue that the module might have many lines of code. I can argue that a class or struct definition can have manly lines of code. How is one case different from the other?
Any argument about encapsulation here is purely ideological. If you have access to the source file, you have access to the private members, period.
The practical problem that arises is when you directly manipulate _x
at multiple points in the file and then one day decide to rename it to _y
. Ignoring the fact things like Find and Replace
and Ctrl + D
exist, and that the worst case resulting from such a change should be compilation errors, this problem exists whether you're accessing the field from within the class or from elsewhere in the module. But yeah, this can be an issue on teams, sure.
Java, where you almost always have one class per file, has exactly the same issue. The common recommendation in Java for people concerned about it is to only access private members via their getters and setters, even within the class.
In D, given module mymod
, you can split your aggregates into individual files and make a package module:
- mymod
-- package.d
-- classA.d
-- classB.d
-- freefuncs.d
Then clients can still treat mymod
as a single module, and you get your ideological purity. But your problem of programmers having access to the private memvers of ClassA
if they have access to classA.d
doesn't go away. It's just been moved to a different module.