[Next] [Previous] [Up] [Top] [Contents] [Index]

2.7 Method Lookup

2.7.3 Examples

For example, consider the following inheritance graph (containing only singly-dispatched methods for the moment):

The partial ordering on objects in this graph defines ABC to be more specific than either AB or AC, and both AB and AC are more specific than A. Thus, methods defined for ABC will be more specific (will override) methods defined in A, AB, or AC, and methods defined in either AB or AC will be more specific (will override) methods defined in A. The AB and AC objects are mutually unordered, and so any methods defined for both AB and AC will be unordered.

If the message m1 is sent to the ABC object, both the implementation of m1 whose formal argument is specialized on the ABC object and the implementation of m1 specialized on A will apply, but the method specialized on ABC will be more specific than the one specialized on A (since ABC is more specific than A), and so ABC's m1 will be chosen. If instead the m1 message were sent to the AB object, then the version of m1 specialized on the A object would be chosen; the version of m1 specialized on ABC would be too specific and so would not apply.

If the m2 message is sent to ABC, then both the version of m2 whose formal argument is specialized on A and the one whose formal is specialized on AC apply. But the partial ordering places the AC object ahead of the A object, and so AC's version of m2 is selected.

If the m3 message is sent to ABC, then both AB's and AC's versions of m3 apply. Neither AB nor AC is the single most-specific object, however; the two objects are mutually incomparable. Since the system cannot select an implementation of m3 automatically without having a good chance of being wrong and so introducing a subtle bug, the system therefore reports an ambiguous message error. The programmer then is responsible for resolving the ambiguity explicitly, typically by writing a method in the child object which resends the message to a particular ancestor; resends are described in section 2.8. Sends of m3 to either AB or AC would be unambiguous, since the other method would not apply.

To illustrate these rules in the presence of multi-methods, consider the following inheritance graph (methods dispatched on two arguments are shown twice in this picture):

Methods m1 in A and m3 in AB illustrate that multiple methods with the same name and number of arguments may be associated with (specialized on) the same object, as long as some other arguments are specialized differently. The following table reports the results of several message sends using this inheritance graph.

message

invoked method or error

explanation

m1(ABC, XYZ)

m1(i@A, j@XZ)

XZ overrides X

m2(ABC, XYZ)

m2(j@AB, k)

AB overrides A

m3(ABC, XYZ)

m3(j@AB, k@XY)

XY overrides unspecialized

m4(AB, XY)

"message not understood"

ABC too specific for AB fi no applicable method

m5(ABC, XYZ)

"message ambiguous"

AB overrides A but XZ overrides X fi
no single most-specific applicable method

m6(ABC, XYZ)

"message ambiguous"

AC overrides unspecialized but XYZ overrides unspecialized fi no single most-specific method