So I'm writing an application where one object has a bunch of delegate objects that it forwards messages to. The idea is that I can say
someObject sendMessage:aMessage
and aMessage will be sent to all of someObject's delegates (for any value of aMessage). The only way I've been able to do this is something like:
sendMessage:aMessage
| sel chunks kwords arglist msg |
chunks := aMessage findTokens:' '.
kwords := Array new:(chunks size).
arglist := Array new:(chunks size).
1 to: (chunks size) do: [:i |
kwords at:i put:((chunks at:i) findTokens:':') at:1.
arglist at:i put:((chunks at:i) findTokens:':') at:2].
sel := ''.
kwords do:[:word | sel := sel,word,':'].
msg := Message selector:sel arguments:arglist.
delegates do:[:del | del perform:msg selector with:msg arguments].
It works, but there has to be a better way. This solution limits the arguments to being strings, and is just plain ugly. Does anyone know a cleaner, better way to forward messages?
BTW, I'm using squeak, but an implementation-independent solution would be prefered ;)
EDIT: I should add that the delegates are of the same class as the object, so I can't just override DoesNotUnderstand:.
Since you want to pass objects in as arguments, you'll have to pass them in as a separate list of using a message pattern like the following:
someObject sendMessage: aSelector withArguments: argumentList
Then you'd implement #sendMessage:withArguments: as:
sendMessage: aSelector withArguments: argumentList
delegates do:[:del | del perform: aSelector withArguments: :argumentList].
and you'd be able to forward arbitrarily complex messages using real objects as args:
| arguments |
arguments := Array with: Object new with: 1234.5 with: ('key'->'value').
someObject sendMessage: #foo:bar:baz: withArguments: arguments
I think this is portable to most dialects as well...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With