digitalmars.D.learn - How to disable assigning a value to a property?
- Jack Applegame (23/23) Jul 06 2021 Code:
- drug (3/30) Jul 06 2021 Something like using different types for arguments in `Register.clock`
- Jack Applegame (3/5) Jul 06 2021 I've been thinking about it. Unfortunately, this is not always
- Dennis (3/6) Jul 06 2021 We're [still awaiting formal assessment on
- Jack Applegame (2/4) Jul 06 2021 Yes, it would help.
- Adam D Ruppe (6/7) Jul 06 2021 You don't. The language always allows `a = b;` to be rewritten as
- Jack Applegame (2/3) Jul 06 2021 And that's sad. It should happen for properties only.
- Mike Parker (2/3) Jul 06 2021 Totally disagree. This is one of my favorite D features.
- Steven Schveighoffer (10/15) Jul 06 2021 Yes, I lament that there is no way to control how people call your
- jfondren (32/35) Jul 06 2021 Some options:
- jfondren (26/28) Jul 06 2021 4.
- Tejas (28/29) Jul 06 2021 Here's another way using ``` std.typecons ```
Code: ```d import std.stdio; struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct Register { Field clock(int a) { writefln("Register.clock(%s)", a); return Field(); } } void main() { Register register; register.clock(1) = 10; // works, good register.clock = 10; // works too, how to disable it? } ``` How to disable `register.clock = 10;` but allow `register.clock(1) = 10;`? I want to get a compilation error on `register.clock = 10;`
Jul 06 2021
06.07.2021 13:06, Jack Applegame пишет:Code: ```d import std.stdio; struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct Register { Field clock(int a) { writefln("Register.clock(%s)", a); return Field(); } } void main() { Register register; register.clock(1) = 10; // works, good register.clock = 10; // works too, how to disable it? } ``` How to disable `register.clock = 10;` but allow `register.clock(1) = 10;`? I want to get a compilation error on `register.clock = 10;`Something like using different types for arguments in `Register.clock` and `Field.opAssign`?
Jul 06 2021
On Tuesday, 6 July 2021 at 10:24:45 UTC, drug wrote:Something like using different types for arguments in `Register.clock` and `Field.opAssign`?I've been thinking about it. Unfortunately, this is not always convenient.
Jul 06 2021
On Tuesday, 6 July 2021 at 10:06:11 UTC, Jack Applegame wrote:How to disable `register.clock = 10;` but allow `register.clock(1) = 10;`? I want to get a compilation error on `register.clock = 10;`We're [still awaiting formal assessment on dip1038](https://forum.dlang.org/thread/sojvxakgruzfvbigzhiu forum.dlang.org), but if that gets in, you can mark `clock` or `Field` ` nodicard`. Otherwise I don't know of a way.
Jul 06 2021
On Tuesday, 6 July 2021 at 10:25:28 UTC, Dennis wrote:We're [still awaiting formal assessment on dip1038](https://forum.dlang.org/thread/sojvxakgruzfvbigzhiu forum.dlang.org), but if that gets in, you can mark `clock` or `Field` ` nodicard`. Otherwise I don't know of a way.Yes, it would help.
Jul 06 2021
On Tuesday, 6 July 2021 at 10:06:11 UTC, Jack Applegame wrote:How to disable `register.clock = 10;`You don't. The language always allows `a = b;` to be rewritten as `a(b);`. Best you can do is use different types for the two arguments. Maybe clock could take a struct Clock { int x; } or something instead.
Jul 06 2021
On Tuesday, 6 July 2021 at 12:33:20 UTC, Adam D Ruppe wrote:The language always allows `a = b;` to be rewritten as `a(b);`.And that's sad. It should happen for properties only.
Jul 06 2021
On Tuesday, 6 July 2021 at 13:27:43 UTC, Jack Applegame wrote:And that's sad. It should happen for properties only.Totally disagree. This is one of my favorite D features.
Jul 06 2021
On 7/6/21 9:27 AM, Jack Applegame wrote:On Tuesday, 6 July 2021 at 12:33:20 UTC, Adam D Ruppe wrote:Yes, I lament that there is no way to control how people call your function. It can result in surprising things, and it means as a library designer you have to consider this usage when picking names. There are a few "draft" DIP proposals (under the old DIP system) here: https://wiki.dlang.org/DIPs But I think the time of being able to make such a disruptive change has passed. For better or worse we have the half-implemented near-useless meaning of ` property`, and basically it's unneeded. -SteveThe language always allows `a = b;` to be rewritten as `a(b);`.And that's sad. It should happen for properties only.
Jul 06 2021
On Tuesday, 6 July 2021 at 10:06:11 UTC, Jack Applegame wrote:How to disable `register.clock = 10;` but allow `register.clock(1) = 10;`? I want to get a compilation error on `register.clock = 10;`Some options: 1. return a temporary struct with an opIndex ```d import std.stdio; struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct ClockAssign { Field opIndex(int a) { writefln("Register.clock(%s)", a); return Field(); } } struct Register { ClockAssign clock() { return ClockAssign(); } } void main() { Register register; register.clock[1] = 10; // works, good //register.clock = 10; // error } ``` 2. https://run.dlang.io/is/bkV64U - keep track of fields and fail at runtime if a field was never initialized (because it was silently discarded in this case). 3. https://run.dlang.io/is/AJM6Vg - hybrid where ClockAssign has an unsafe pointer that the compiler complains about :/
Jul 06 2021
On Tuesday, 6 July 2021 at 15:24:37 UTC, jfondren wrote:3. https://run.dlang.io/is/AJM6Vg - hybrid where ClockAssign has an unsafe pointer that the compiler complains about :/4. ```d import std.stdio; struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct ClockAssign { Field[] clocks; void opIndexAssign(int a, int b) { writefln("Register.clock(%s)", a); clocks ~= Field(); clocks[$-1] = b; } } struct Register { ClockAssign clock; } void main() { Register register; register.clock[1] = 10; // register.clock = 10; // error } ```
Jul 06 2021
On Tuesday, 6 July 2021 at 10:06:11 UTC, Jack Applegame wrote:Here's another way using ``` std.typecons ``` ```d import std.stdio; import std.typecons; alias input = Typedef!int; //new code struct Field { void opAssign(int a) { writefln("Field.opAssign(%s)", a); } } struct Register { Field clock(input a) { writefln("Register.clock(%s)", cast(int)a); //note the cast return Field(); } } void main() { input ip = 1; Register register; register.clock(ip) = 10; // works, good //register.clock = 10; // works too, how to disable it? EDIT: Now it doesn't work :) } ``` You will have to either cast your literal, or provide a variable with the new type as input though, so it is also not perfect.
Jul 06 2021