2

Pharo Smalltalk - Message forwarding, is it possible to intercept a message and redirect it to another Object (instance)?

In Objective-C there's forwardInvocation: that gets called right before an exception is thrown so you can do something about the message you received and know nothing about.

Is there something similar in Smalltalk do I can redirect a message to a delegate?

unom
  • 11,438
  • 4
  • 34
  • 54
  • 1
    What are you trying to accomplish? Do you have an example where such a feature would be useful? You can use DNU as explained in Leo's answer. But keep in mind that in the vast majority of cases you shouldn't need any kind of "trick." – Leandro Caniglia Jan 29 '15 at 23:33

1 Answers1

5

Smalltalk has doesNotUnderstand: aMessage which is sent to the receiver in place of an otherwise undefined method. You can override it and do whatever you wish (e.g. forward the message to another object, log it to disk, ...), for instance:

doesNotUnderstand: aMessage 
    aMessage sendTo: self delegate.

If you want to "intercept" messages which are actually defined on an object, you have two options:

  1. subclassing and using your own objects
  2. using method wrappers to replace the original method definitons which allows all kinds of manipulations (redirecting messages to new receivers, executing pre- and post-message-hooks, preventing the execution of the wrapped method, etc).
Leo
  • 37,640
  • 8
  • 75
  • 100
  • 3
    The seminal text on _Method Wrapping_ is [Brant, John, Brian Foote, Ralph E. Johnson und Don Roberts: _Wrappers to the Rescue_](http://www.laputan.org/pub/foote/brant.pdf). It's very interesting to read. A Pharo implementation can be found in [ObjectProfile's Spy framework](http://smalltalkhub.com/#!/~ObjectProfile/S2py) – MartinW Jan 30 '15 at 06:46
  • 1
    Just keep in mind that using `#doesNotUnderstand` *will* be slower than simple message sends since a) the entire stack will be searched first and b) the VM has to reify the message object (granted, both won't take long, but it's important to know). – Max Leske Jan 30 '15 at 07:21
  • Hello again, I'm back at this subject again, there are some issues. Presume I want to forward a message that conform to the Object protocol, this message is so basic that since the forwarder itself is an Object it means I really can't use #doesNotUnderstand since it does understand it. Is it possible to subClass the redirector "object" from a more basic type than Object to be able to forward it? – unom Sep 06 '15 at 10:50
  • Managed to find the answer, there was a method allMethodsInCategory: that has been deprecated in Pharo 3.0 and later in favor of allSelectorsInProtocol: which does what I want. Add this to the answer and I'll accept it, it's very detailed so thank you! See here: http://stackoverflow.com/questions/32422955/pharo-smalltalk-how-can-i-check-if-a-message-conforms-to-a-protocol-defined-in Some other dialects have methodsInProtocol: all the same. – unom Sep 09 '15 at 22:13