The message/4
predicate is used to ask whether a message is
defined for a class or to find what messages are defined for a class,
etc. It does not distinguish between messages whose methods are
defined in the class itself and those that are inherited from a
superclass.
The direct_message/4
predicate is used to ask whether a message is
not only defined for a class, but whether the method for that message
is defined in the class itself. It can also be used to determine
which methods are defined in a class. This ability to look inside a
class definition makes direct_message/4
an egregious violator of
the principle of information hiding. Thus it, like
class_ancestor/2
, should mainly be confined to use in programmer
support applications.
Both message/4
and direct_message/4
take the message operator
as an argument, along with the class, message name and arity. Hence it
is possible to use these predicates to ask about get, put or send
messages.
It is not possible to ask about a class's slots, nor should it be. However, it is possible (and quite reasonable) to ask about the get and put messages that are defined for a class. For example, the following goal finds all the 1-argument messages that are defined for both the get and put message operators in the class Class.
| ?- setof(Message, (message(Class, <<, Msg, 1), message(Class, >>, Msg, 1)), L).
There may or may not be slots corresponding to these messages; that detail is hidden in the definition of Class. However, it should be possible to use Class as if the slots were there.
As an example, recall the polar coordinate interface to the point
class, which defined get and put methods for r
and theta
, even
though data was represented inside an object by rectangular
coordinates x
and y
.