Domain of Attribute

The attribute radius of class circle obviously should be a positive number. Does being public mean that any absurd value can be assigned to it, and the circle class member is still legitimate? Actually, an attribute definition may also include a domain, which is the set of all allowed values of the attribute. The Shang interpreter monitors every value assigned to an attribute, attempt to set an attribute to an invalid value will be stopped.

The syntax for specifying the domain of an attribute is the keyword in followed by a set.

   global._RP = (0+ to inf);
   circle = class 
              public radius = 1 in _RP;
              auto   perimeter = () -> 2 * pi * parent.radius;
              auto   area = () -> pi * (parent.radius)^2;
            end
Here _RP is a global variable predefined to be the interval of all positive scalars. With this domain specified, now only positive numbers can be assigned to the radius field.

When an attribute is declared without specifying a domain, its domain will be the default value _ALL, which is the set of everything. Note that whenever a domain is specified, the default value of the attribute must also be specified, since the default constructor of the class will create a member of the class that has only default values. If no default value is given, then null is used. But then if there is a domain defined, null may not be in the domain, and the constructor may return an invalid object.

Domain is most useful for public attributes. In the following example, each attribute of a person is public, and therefore can be accessed and modified directly. Yet, only valid values can be assigned to the attributes. In many languages, to protect the integrity of data, such attributes must be made private, and direct access to them disallowed. Instead, function attributes called ``getters'' and ``setters'' are used to access and modify their values (see the example in 7.2.1).

person = class
              public gender = "M" in {"F", "M"};
              public age = 1 in 1 : 150;
              public first = "Mark" in ~/[A-Za-z][A-Za-z]*/;
              public last = "Brown" in ~/[A-Za-z][A-Za-z]*/;
         end
Although domain makes most sense in the case of public field, a private field can have a domain as well.

oz 2009-12-22