Validation of member attribute modification

Normally a class behaves the way it's designed to. However, if it inherits from a super class, in theory, its members automatically have all the member attributes of the super class, and some of these attributes may reduce a sub class member into illegal state. For example, consider a circle class that inherits from a super class ellipse. The two axes of an ellipse x are called x.a and x.b. x is considered an ellipse if x.a is equal to x.b. However, x as an ellipse may be able to change the values of a or b so that x.a is no longer equal to x.b. This will cause a circle to enter an illegal state.

In Shang, a class may have a common attribute validate which verifies that the state of the class member is valid. Whenever an attempt to modify a class member is made, the modification will be temporarily made and then validate is implicitly called. If it returns non-zero value, the validation is passed and the modification will take effect. Otherwise, the modification will be reversed.

Note that validate is called whenever an update of class member state is made. If x.a must equal to x.b in order for x to be valid, a simultaneous assignment (x.a, x.b) = (v, v) must be done in order to pass validation.

global.ellipse = class
        title = "ellipse";
        public a = 1 in (0 to inf);
        public b = 5 in (0 to inf);
        auto longaxis = () -> max(parent.a, parent.b);
        auto shortaxis = () -> min(parent.a, parent.b);
        auto area = () -> pi * parent.a * parent.b;
        new = (a, b) -> ();
end

circle = class
        super = global.ellipse;
        title = "circle";
        auto radius = () -> parent.a;
        auto longaxis = () -> parent.radius;
        auto shortaxis = () -> parent.radius;
        auto perimeter = () -> 2 * pi * parent.radius;
        common set_radius = r -> ((parent.a, parent.b) = (r, r));
        common validate = () -> (parent.a == parent.b);
        new = (a, b) -> ();
end

u = circle.new(3, 3) 
u.a = 5; // won't work
Note that without the validate function, u.a = 5 will change u to an ellipse with a = 5, b = 3.

oz 2009-12-22