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.
}

Reply via email to