Get and put methods are not automatically generated for private and protected
slots. Those slots are accessed by the fetch_slot/2
and
store_slot/2
predicates, which may only appear in the body of a
method clause and which always operate on the object to which the
message is sent. It is not possible to access the slots of another
object with these predicates.
You may declare a slot to be private or protected in order to limit access to it. However, it is still possible, and frequently useful, to define get and put methods for such a slot.
For example, if numerator and denominator slots of the rational number class were private rather than public, it would be possible to define put methods to ensure that the denominator is never 0 and that the numerator and denominator are relatively prime. The get methods merely fetch slot values, but they need to be defined explicitly, since the slots are private. The new definition of the rational number class might start as follows:
:- class rational = [num:integer=0, denom:integer=1]. Self >> num(N) :- fetch_slot(num, N). Self >> denom(D) :- fetch_slot(denom, D). Self >> (N/D) :- Self >> num(N), Self >> denom(D).
One of the put methods for the class might be
Self << num(NO) :- fetch_slot(denom, DO) reduce(NO, DO, N, D), store_slot(num, N), store_slot(denom, D).
where the reduce/4
predicate would be defined to divide NO
and
DO
by their greatest common divisor, producing N
and D
,
respectively.
The definition of reduce/4
and the remaining put methods is left
as an exercise. The put methods should fail for any message that
attempts to set the denominator to 0.