37.2.2 Method Declarations

Method-clauses are declared similarly to Prolog clauses. Thus a method-clause can be either a unit clause or a rule. We also allow a default catch-all method-clause as the last clause in an object body. The catch-all clause has as its head a Prolog variable, in order to match messages that are not previously defined or inherited in the object. It can be used to implement alternative inheritance mechanisms.

Goals in the body of a rule have the normal control structures of Prolog:

:P, :Q
Conjunction
:P; :Q
Disjunction
!
Cut
\+ :P
Negation
:P -> :Q
:P -> :Q; :R
if(:P, :Q, :R)
If-then[-else]
?A = ?B
Unification

Atomic goals in the body of a method-clause may be one of the following:

:goal
to call the Prolog predicate goal in the source module.
m:goal
to call the Prolog predicate goal in module m.
goal
to send the message goal to the object Self.
::goal
to send the message goal to a method that may be defined locally or inherited by the object.
<:goal
to delegate the message goal to a method that may be defined locally or inherited by the object.
object::goal
to send the message goal to object object.
object<:goal
to delegate the message goal to object object.

Message sending and delegation will be explained later (see Obj Self).

The following is a definition for the object list_object. It is constructed from three methods: append/3, member/2, and length/2. Note that the calls to append/3 and length/2 are to the local definition, whereas the member/2 call is to the predicate imported from the Prolog library module lists.

     list_object :: {
             :- :use_module(library(lists), [append/3,member/2]) &
     
             append([], L, L) &
             append([X|L1], L2, [X|L3]) :-
                     :: append(L1, L2, L3) &
     
             member(X, L) :-
                     :member(X,L) &
     
             length([], 0) &
             length([_|L], N) :-
                     :: length(L, N1),
                     :(N is N1+1)
             }.

The following object apt_1 could be part of a larger database about free apartments in a real-estate agency:

     apt_1 :: {
             super(apartment) &
     
             street_name('York') &
             street_number(100) &
             wall_color(white) &
             floor_surface(wood)
             }.

Another way to define apt_1 is by using attributes. These can be retrieved and modified efficiently by the methods get/1 and set/1 respectively.

     apt_1 :: {
             super(apartment) &
     
             attributes([
                    street_name('York'),
                    street_number(100),
                    wall_color(white),
                    floor_surface(wood)])
             }.