Thread overview |
---|
September 24, 2016 Lazily evaluated property pointing to read only object | ||||
---|---|---|---|---|
| ||||
I'm trying to figure out how to best write a class with a property that is only evaluated when it's called for the first time. And that returns an object which shouldn't be modifiable a part of the owning class. I've had a go at doing something like this but am not very sure if this is how to go about it. class Obj { string _s; this() { this(""); } this(string s) { _s = s; } @property string desc() const { return _s; } @property void desc(string s) { _s = s; } override string toString() const { return _s; } } class ConstProp { Obj _o; string _s; this(string s) { _s = s; } const(Obj) lazily() { if (_o is null) { _o = new Obj("working " ~ _s); } return cast(const(Obj)) _o; } } void main() { auto c = new ConstProp("test"); writeln(c.lazily); writeln(c.lazily.desc); } |
September 24, 2016 Re: Lazily evaluated property pointing to read only object | ||||
---|---|---|---|---|
| ||||
Posted in reply to mikey | On Saturday, 24 September 2016 at 09:08:52 UTC, mikey wrote: > I'm trying to figure out how to best write a class with a property that is only evaluated when it's called for the first time. And that returns an object which shouldn't be modifiable a part of the owning class. > > I've had a go at doing something like this but am not very sure if this is how to go about it. > [...] > > > const(Obj) lazily() { > if (_o is null) { > _o = new Obj("working " ~ _s); > } > return cast(const(Obj)) _o; > } > } You don't need to cast, from "mutable" to "const" is implicit: https://dlang.org/spec/const3.html#implicit_conversions |
September 24, 2016 Re: Lazily evaluated property pointing to read only object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Saturday, 24 September 2016 at 10:16:34 UTC, Basile B. wrote:
> You don't need to cast, from "mutable" to "const" is implicit:
> https://dlang.org/spec/const3.html#implicit_conversions
Ok, but using const would be an accepted way of doing this? The options I could see were to have "_o" as a const or immutable type and just create a const on the first call to the lazily evaluated property, or to do what I did and have "_o" as a non-const and then convert it to cost on the way out. However
To store it as const I guess I'd have to make it a non-const pointer to a const object, and is that not kind of what immutable is?
|
September 24, 2016 Re: Lazily evaluated property pointing to read only object | ||||
---|---|---|---|---|
| ||||
Posted in reply to mikey | On Saturday, 24 September 2016 at 10:59:50 UTC, mikey wrote:
> On Saturday, 24 September 2016 at 10:16:34 UTC, Basile B. wrote:
>> You don't need to cast, from "mutable" to "const" is implicit:
>> https://dlang.org/spec/const3.html#implicit_conversions
>
> Ok, but using const would be an accepted way of doing this? The options I could see were to have "_o" as a const or immutable type and just create a const on the first call to the lazily evaluated property, or to do what I did and have "_o" as a non-const and then convert it to cost on the way out. However
>
> To store it as const I guess I'd have to make it a non-const pointer to a const object, and is that not kind of what immutable is?
Yes, the problem is that if you want to create a true const(Object) (with const part of the type) you have to initialize it in a constructor (so no lazyness). It indeed looks like the immutable mechanism. I don't know **exactly** why but I guess that's a special case for classes since there's no other way to initialize them.
Finally, with the property your object is seen as const(Object) outside. The only difference is inside ConstProp.
|
September 27, 2016 Re: Lazily evaluated property pointing to read only object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Saturday, 24 September 2016 at 11:51:56 UTC, Basile B. wrote:
> On Saturday, 24 September 2016 at 10:59:50 UTC, mikey wrote:
>> On Saturday, 24 September 2016 at 10:16:34 UTC, Basile B. wrote:
>>> You don't need to cast, from "mutable" to "const" is implicit:
>>> https://dlang.org/spec/const3.html#implicit_conversions
>>
>> Ok, but using const would be an accepted way of doing this? The options I could see were to have "_o" as a const or immutable type and just create a const on the first call to the lazily evaluated property, or to do what I did and have "_o" as a non-const and then convert it to cost on the way out. However
>>
>> To store it as const I guess I'd have to make it a non-const pointer to a const object, and is that not kind of what immutable is?
>
> Yes, the problem is that if you want to create a true const(Object) (with const part of the type) you have to initialize it in a constructor (so no lazyness). It indeed looks like the immutable mechanism. I don't know **exactly** why but I guess that's a special case for classes since there's no other way to initialize them.
>
> Finally, with the property your object is seen as const(Object) outside. The only difference is inside ConstProp.
use Rebindable:
class Obj {
string _s;
this()pure{
this("");
}
this(string s)pure{
_s = s;
}
@property string desc() const { return _s; }
@property void desc(string s) { _s = s; }
override string toString() const {
return _s;
}
}
class ConstProp {
import std.typecons : Rebindable;
Rebindable!(immutable Obj) _o;
string _s;
this(string s) {
_s = s;
}
immutable(Obj) lazily(){
if (_o is null) {
_o = new Obj("working " ~ _s);
}
return _o;
}
}
|
Copyright © 1999-2021 by the D Language Foundation