Direct Slot Access

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.