`restricted` member variables
Mike Parker
aldacron at gmail.com
Tue Jun 21 00:33:24 UTC 2022
On Monday, 20 June 2022 at 15:49:20 UTC, Paul Backus wrote:
>
> I'm not convinced the extra granularity is worth adding an
> entire new attribute for.
My main motivation was the case of having a setter with a
contract that serves as a cheap invariant:
```d
class Foo {
int _x;
void x(int newX)
in (newX < 1000)
{ _x = newX; }
}
```
If we replace that with an invariant, the problem isn't that the
module has access to the protected variable. The problem is that
any function in the module that does access the variable is
effectively part of the public API, thereby violating the
guarantee that the invariant is checked when accessed through the
public API. So that is solvable without a new level of protection
just by making sure that every write to the variable from within
the module triggers the invariant check.
The purpose of the function contracts is to validate function
input and output, but for a setter like the above it effectively
serves as an invariant as long as nothing writes directly to `_x`
outside the setter. And from that perspective, it would be nice
if there were a way to guarantee that happens both within the
module and within the class.
So I guess what I'm really after isn't `restricted`, but a
targeted invariant, perhaps of the form`invariant(_x) _x < 1000`
that only triggers when the protected variable is written to. It
just seems overkill to me that an invariant for one member
variable is run on calls to every member function.
But that also isn't wholly necessary. I can always wrap `_x` in a
struct, give it a setter and an invariant/contract, and put that
in a separate module.
So yeah, `restricted` is pointless. The targeted invariant would
be nice, though.
More information about the Digitalmars-d
mailing list