Invariants for methods
bearophile
bearophileHUGS at lycos.com
Thu Nov 18 10:08:18 PST 2010
Jens Mueller:
> I have a rectangle and one of its methods moves the upper left
> of the rectangle. I have two invariants when moving a rectangle: The
> width and the height do not change. I could do something like the
> following:
>
> void move(...) {
> int currentWidth = width;
> int currentHeight = height;
> // moving the rectangle here
> assert(currentWidth == width);
> assert(currentHeight == height);
> }
Probably you need one basic feature of DesignByContract that is missing still in D2, the "old" that allows at the end of a method to know the originals. It was discussed two or more times:
http://www.digitalmars.com/d/archives/digitalmars/D/why_no_old_operator_in_function_postconditions_as_in_Eiffel_54654.html
http://www.digitalmars.com/d/archives/digitalmars/D/Communicating_between_in_and_out_contracts_98252.html
Once the feature is implemented you may solve your problem like this (minus syntax changes, but other solutions are possible):
void move(...)
in {
// ...
} out {
assert(width == old.width);
assert(height == old.height);
} body {
// moving the rectangle here
}
The problem of implementing the old was solved in C#4, it is named PrestateValues(OldValue), see page 8 here:
http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf
So probably this problem may be solved in D2 too.
To solve this problem currently you may need to use ghost fields in your struct/class that memorize the older values... ghost fields wrapped in version(unittest) {...} or some version(debug). This is a bad solution.
Bye,
bearophile
More information about the Digitalmars-d
mailing list