www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Readonly field for class type

reply Andrey <andrey kabylin.ru> writes:
Hello, is there way to declare read only field for class type 
with ability to call inner non constant methods? i.e.:

 class A {
     int value = 12;
     void updateValue() {
         value = 13;
     }
 }
 
 class B {
     const A a;
 
     this() {
         a = new A();
         a.updateValue();  // error: mutable method is not 
 callable using const object
     }
 }
Mar 15 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 15 March 2018 at 10:16:49 UTC, Andrey wrote:
 Hello, is there way to declare read only field for class type 
 with ability to call inner non constant methods? i.e.:

 class A {
     int value = 12;
     void updateValue() {
         value = 13;
     }
 }
 
 class B {
     const A a;
 
     this() {
         a = new A();
         a.updateValue();  // error: mutable method is not 
 callable using const object
     }
 }
class A { private int _value = 12; int value() property { return _value; } void updateValue() { value = 13; } } ... auto a = new A(); writeln(a.value); a.updateValue(); writeln(a.value);
Mar 15 2018
parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:

 class A {
     private int _value = 12;

     int value()  property { return _value; }
     void updateValue() { value = 13; }
 }

 ...
 auto a = new A();
 writeln(a.value);
 a.updateValue();
 writeln(a.value);
Sorry. I overlooked that B.a is const.
Mar 15 2018
parent reply Seb <seb wilzba.ch> writes:
On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:
 On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:

 class A {
     private int _value = 12;

     int value()  property { return _value; }
     void updateValue() { value = 13; }
 }

 ...
 auto a = new A();
 writeln(a.value);
 a.updateValue();
 writeln(a.value);
Sorry. I overlooked that B.a is const.
It still works, the `value` just needs to be `const` (or `inout`) and _value needs to be used in updateValue: class A { private int _value = 12; int value() const { return _value; } void updateValue() { _value = 13; } } auto a = new A(); writeln(a.value); a.updateValue(); writeln(a.value); In action: https://run.dlang.io/is/Tk1rY1 Robert: If you need this a lot, the accessors package might be interesting to you: https://code.dlang.org/packages/accessors
Mar 15 2018
next sibling parent Seb <seb wilzba.ch> writes:
On Thursday, 15 March 2018 at 13:44:20 UTC, Seb wrote:
 On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:
 On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:

 [...]
Sorry. I overlooked that B.a is const.
It still works, the `value` just needs to be `const` (or `inout`) and _value needs to be used in updateValue: class A { private int _value = 12; int value() const { return _value; } void updateValue() { _value = 13; } } auto a = new A(); writeln(a.value); a.updateValue(); writeln(a.value); In action: https://run.dlang.io/is/Tk1rY1 Robert: If you need this a lot, the accessors package might be interesting to you: https://code.dlang.org/packages/accessors
(I meant Andrey - sorry)
Mar 15 2018
prev sibling parent Seb <seb wilzba.ch> writes:
On Thursday, 15 March 2018 at 13:44:20 UTC, Seb wrote:
 On Thursday, 15 March 2018 at 10:57:52 UTC, Mike Parker wrote:
 On Thursday, 15 March 2018 at 10:55:16 UTC, Mike Parker wrote:

 class A {
     private int _value = 12;

     int value()  property { return _value; }
     void updateValue() { value = 13; }
 }

 ...
 auto a = new A();
 writeln(a.value);
 a.updateValue();
 writeln(a.value);
Sorry. I overlooked that B.a is const.
It still works, the `value` just needs to be `const` (or `inout`) and _value needs to be used in updateValue: class A { private int _value = 12; int value() const { return _value; } void updateValue() { _value = 13; } } auto a = new A(); writeln(a.value); a.updateValue(); writeln(a.value); In action: https://run.dlang.io/is/Tk1rY1 Robert: If you need this a lot, the accessors package might be interesting to you: https://code.dlang.org/packages/accessors
... and I didn't add `const` to A -> https://run.dlang.io/is/QObN1w but better have a look at Simen's response (https://forum.dlang.org/post/ottyywbmrwgfabgpfehk forum.dlang.org), it's what you are looking for. I read too quickly and only have of it :/
Mar 15 2018
prev sibling next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 15 March 2018 at 10:16:49 UTC, Andrey wrote:
 Hello, is there way to declare read only field for class type 
 with ability to call inner non constant methods? i.e.:

 class A {
     int value = 12;
     void updateValue() {
         value = 13;
     }
 }
 
 class B {
     const A a;
 
     this() {
         a = new A();
         a.updateValue();  // error: mutable method is not 
 callable using const object
     }
 }
You can do this: class B { private A _a; property const(A) a() { return _a; } this() { _a = new A(); _a.updateValue(); } } -- Simen
Mar 15 2018
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/15/2018 03:16 AM, Andrey wrote:
 Hello, is there way to declare read only field for class type with 
 ability to call inner non constant methods? i.e.:
 
 class A {
     int value = 12;
     void updateValue() {
         value = 13;
     }
 }

 class B {
     const A a;

     this() {
         a = new A();
         a.updateValue();  // error: mutable method is not callable 
 using const object
     }
 }
Another option is assigning a pre-made A to the member: class A { int value = 12; void updateValue() { value = 13; } } // Magic recipe is moved here: A makeA() { auto a = new A(); a.updateValue(); return a; } class B { const A a; this() { a = makeA(); } } void main() { auto b = new B(); } Which can be compressed into a lambda in the constructor: this() { a = { // This 'a' is a local variable inside the lambda: auto a = new A(); a.updateValue(); return a; }(); } Ali
Mar 15 2018