As mentioned above, it is possible to specify a term class as the type of a slot of some other object. For example, we might declare
:- class colored_rectangle = [
public origin:point,
public size:size,
public color:rgb_color].
This will store an rgb_color object (i.e., a color/3 term) in
the color slot of each colored_rectangle object.
Unfortunately, though, SICStus Objects cannot tell what is the best
way to store a term object, and therefore it stores it the same way it
stores a slot declared to be of term type: using the Prolog
database. This has all the efficiency disadvantages of term
slots. In this
case, however, we know that all that really needs to be saved in order
to save an rgb_color object is the three arguments. We also know
that each of these arguments is a floating point number, and because
precision isn't terribly critical in representating colors, each of
these numbers can be stored as a float, rather than a double.
In effect, we know that the essence of a rgb_color object is
these three numbers; if we have them, we can easily construct the
color/3 term. If we provide this information in the declaration
of the rgb_color class, SICStus Objects can store instances of
the rgb_color class as 3 separate floats, rather than as a term,
significantly improving the performance of creating or destroying a
colored_rectangle object, as well as accessing or modifying its
color slot.
The essence of a term class is specified with the following form of
class declaration:
:- class ClassName = term(Term, Constraint, Essence).
where Essence is of the form
[Name1:Type1=i[Variable1], Name2:Type2=i[Variable2], ...]
and each Name is a distinct atom naming a slot, each
Type is a slot type as specified in obj-scl-slt, and each
Variable is an unbound variable appering in Term.
Providing a term essence not only makes storage of terms in ordinary
object slots more efficient, it also gives a name to each
“essential” slot of the term class. This allows you to use
fetch_slot to fetch the slots of this class.
To extend our rgb_color example, we might introduce the rgb_color
class with this declaration:
:- class rgb_color =
term(color(Red,Green,Blue),
(float(Red), Red >= 0.0, Red =< 1.0,
float(Green), Green >= 0.0, Green =< 1.0,
float(Blue), Blue >= 0.0, Blue =< 1.0),
[red:float=Red, green:float=Green, blue:float=Blue]).
This declaration defines the rgb_color class exactly as the
example declaration of the previous section: every color/3 term
whose arguments are all floating point numbers between 0.0 and 1.0
inclusive are instances of rgb_color. The difference is that with
this declaration, ordinary classes that have slots of type
rgb_color, such as the colored_rectangle example above,
will be stored more efficiently, and their rgb_color
slots will be accessed and modified much more efficiently.
Also, it will be possible to use fetch_slot(red, Red) in the
methods of the rgb_color class to fetch to red component of the
message recipient, and similarly for green and blue.