Thread overview
Readonly field for class type
Mar 15, 2018
Andrey
Mar 15, 2018
Mike Parker
Mar 15, 2018
Mike Parker
Mar 15, 2018
Seb
Mar 15, 2018
Seb
Mar 15, 2018
Seb
Mar 15, 2018
Simen Kjærås
Mar 15, 2018
Ali Çehreli
March 15, 2018
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
>     }
> }



March 15, 2018
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);
March 15, 2018
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
March 15, 2018
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.
March 15, 2018
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
March 15, 2018
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)
March 15, 2018
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 :/
March 15, 2018
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