Pharo Smalltalk - How can I check if a message con

2019-06-20 17:08发布

问题:

I'm looking at this form an Objective-C background so be gentle. The experiment looks like this:

Object1 has an instance variable named delegate.

Object1 receives a message and the proceeds to check if delegate implements a specific protocol (whose name is known beforehand), if it does, then it checks if the message is among the protocol's implemented methods. It then makes a decision on how to interact with the delegate and so on.

In Objective-C one has to define clear Protocols, usually stored in different files, and conforming to a protocol is checked by the compiler. In Pharo I can't seem to find how to check for this kind of information even though the Browser has a whole column dedicated to protocols, and beside grouping methods they seem to do very little.

回答1:

Here are some few alternatives that could help you with this:

  1. Get the collection of all selectors that populate the object's class:
    • anObject class selectors
  2. Get the collection of all selectors that populate the object's class and all its superclasses:
    • anObject class allSelectors
  3. Ask the class whether it implements a given message (for its instances):
    • anObject class canUnderstand: #putTheSelectorHere
  4. Ask the object whether it understands a given message:
    • anObject respondsTo: #methodSelectorHere
  5. Use the MessageNotUnderstood mechanism:
    • (see explanation below)

In 1 and 2 above you can use the returned collections to check whether they include a certain selector you are interested in. Features 3, 4 and 5 have a more dynamic nature. For example, you can refine the #doesNotUnderstand: method in your class as follows:

MyClass >> #doesNotUnderstand: aMessage
    (delegate respondsTo: aMessage selector)
        ifTrue: [^delegate
           perform: aMessage selector
           withArguments: aMessage arguments].
    ^super doesNotUnderstand: aMessage

This way, if your object receives a message that it does not understand, it will first receive the #doesNotUnderstand: message (without you having to do anything for this to happen) and here you could decide (e.g., by using the #respondsTo: message) whether to delegate it or not. If not, you can just relay on the default behavior (super doesNotUnderstand:) which would signal de MessageNotUnderstood exception.

Of course, there is a 6th option, which would be for the sender of the message to handle the MNU exception, but I don't think this is what you are looking for here.



回答2:

There is the proxies work in Ghost/Marea and the original Smalltalk wrappers to the rescue I'm not sure the proxies have been updated for the latest Pharo version. Latest ghost version seems to be here