Instance methods allow each object in a class to have its own method for handling a specified message. For example, in a push-button class it would be convenient for each instance (each push-button) to have its own method for responding to being pressed.
The declaration
:- instance_method Name/Arity, ....
inside a class definition states that the message Name/Arity supports instance methods. If the class definition defines a method for this message, it will be treated as a default method for the message.
The define_method/3
predicate installs a method for an object of
the class, and the undefine_method/3
predicate removes that
method.
Suppose that the date_stamp
class, defined earlier, declared an
instance method to print the year of a date_stamp
instance.
:- instance_method print_year/1. Self <- print_year(Stream) :- Self >> year(Y0), Y1 is YO + 1970, format(Stream, "~d", [Y1]).
The arithmetic is necessary because UNIX dates are based on January 1, 1970.
If a particular date_stamp
object's date were to be printed in
Roman numerals, it could be given a different print_year
method, using
the define_method/3
predicate.
| ?- create(date_stamp, DateObj), define_method(DateObj, print_year(Stream), print_roman_year(Stream, DateObj)).
If this date_stamp
object is created in 1994, then a
print_year
message sent to it would print the current year as
MCMXCIV
Defining the predicate print_roman_year/2
is left as an exercise. It
must be able to access the year
slot of a date_stamp
object. Because
it is not defined by a method clause within the class definition,
print_roman_year/2
cannot use the get_slot/2
predicate.
None of instance_method/1
, define_method/3
,
undefine_method/3
specify a message operator. Instance methods can
only be defined for send messages.