`restricted` member variables
The Zealot
zod at zod.zod
Thu Jun 23 10:35:31 UTC 2022
On Thursday, 23 June 2022 at 03:10:46 UTC, Mike Parker wrote:
> On Thursday, 23 June 2022 at 01:45:22 UTC, Paul Backus wrote:
>
>> Your proposal would lead to the following situation:
>>
>> struct EvenNumber
>> {
>> private int n;
>> invariant (n & 1 == 0);
>>
>> this(int n) { this.n = n; }
>>
>> void addTwoMethod() { this.n++; this.n++; } // ok
>> }
>>
>> void addTwoUFCS(ref EvenNumber this_)
>> {
>> this_.n++; this_.n++; // error - violates invariant
>> }
>
> I could live with that particular inconsistency. The bigger
> downside I see is that you'd potentially have multiple
> invariant checks for the same class on a single function call.
> And whether that's acceptable depends on how common this is in
> practice.
>
>>
>> IMO the correct way to view this is that code in the same
>> module as a class is part of the class's implementation, just
>> as much as code in the actual class body. (Or if you prefer,
>> they are both part of the module's implementation, since the
>> module is the fundamental unit of decomposition here, not the
>> class.)
>>
>
> As long as the invariant checks only run on those functions
> that actually touch a private member. There would potentially
> be checks for multiple classes running before and after each
> function call, so doing it on every function call in the module
> is overkill.
>
> And that would also have to include any public member functions
> of any classes that access any private members of other classes
> in the same module. It seems more complex to implement than
> just doing a rewrite to getters/setters.
>
> An even simpler option would be to disallow access to any
> private members in a module on classes that have invariants.
> Not something I'd advocate, but a possibility.
Another idea would be to force the programmer to specify _when_
the invariant checks happen. :
```
struct EvenNumber
{
private int n;
invariant (n & 1 == 0);
this(int n) { this.n = n; }
void addTwoMethod() { this.n++; this.n++; } // ok
}
void addTwoUFCS(ref EvenNumber this_)
{
invariant(enter) { // invariant is checked here
this_.n++; this_.n++;
}
invariant(exit) {
this_.n++; this_.n++;
} // invariant is checked here
invariant(access) {
this_.n++; // invariant is checked here
this_.n++; // invariant is checked here
}
}
```
More information about the Digitalmars-d
mailing list