On Sunday, 27 May 2018 at 05:25:53 UTC, IntegratedDimensions
wrote:
Re: Friends in D, a new idiom?
In D, there's no exact equivalent to friend, but there are a few
more specialized tools at your disposal. Normally all code in the
same module is essentially a friend, so if the classes you are
dealing with are tightly coupled, they can simply be in the same
module.
For example:
module m;
class C {
// This is still visible in the same module.
// See https://dlang.org/spec/attribute.html#VisibilityAttribute
private int data;
...
}
class CAccessor {
C _this;
this(C c) {
_this = c;
}
@property void data(int v) {
_this.data = v;
}
...
}
Initially I thought nested classes contained an inherent super
but I guess that is not the case?
Super is for inheritance rather than inner classes. So another
way to tackle your problem using super would be this:
class C {
protected int _data;
@property int data() {
return _data;
}
}
class CAccessor : C {
@property void data(int v) {
_data = v;
}
C toC() {
return this;
}
}
I also imagine that one could enhance this so that write access
could also be allowed by certain types.
The 'package' visibility attribute can also be given a parameter
if you need to limit access only to certain module.
Any ideas about this type of pattern, how to make it better,
already exists etc?
You might be looking for the "Builder Pattern" which uses a
separate object to construct and modify objects, and then it
creates a read-only object with those values upon request.
Also, I would recommend using "const" to control access as well.
Setter methods will not be const, but getters will be. Those
that have a `const(C)` reference will only be able to read, and
those with a `C` will be able to call all methods.
For example:
class C {
private int _data;
@property int data() const { return _data; }
@property void data(int v) { _data = v; }
}
void main() {
C a = new C();
const(C) b = a;
a.data(3);
a.data();
b.data();
// b.data(4); Compile error.
}