Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pharo Smalltalk - How can I check if a message conforms to a protocol defined in another object's Class?

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.

like image 479
unom Avatar asked Sep 06 '15 11:09

unom


2 Answers

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.

like image 101
Leandro Caniglia Avatar answered Sep 28 '22 05:09

Leandro Caniglia


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

like image 23
Stephan Eggermont Avatar answered Sep 28 '22 05:09

Stephan Eggermont