[ENH] Message lookup-failure overrides

Brian Rice water at tunes.org
Tue Mar 21 00:06:25 PST 2006


Similar to Smalltalk's doesNotUnderstand: or Ruby's method_missing(),  
in the sense that they can be used to override and delegate behavior,  
I have added hooks to override the handling MethodNotFound per  
argument in the given message-send.

MethodNotFound is raised by "#selector notFoundOn: {args...}" by the  
VM and therefore does not allow PMD-based overrides.

The new hook is #didNotUnderstand:at: taking a Message object and the  
argument position that the main object played. The way it works is  
easiest to show with the actual code from condition-epilogue.slate:

selector@(Symbol traits) notFoundOn: arguments &optionals: optionals
"Query the arguments for an abnormal handler before signalling  
MethodNotFound."
[| message |
   message: (Message sending: selector to: arguments &optionals:  
optionals).
   arguments doWithIndex:
     [| :arg :index | (arg didNotUnderstand: message at: index)  
ifNotNilDo:
       [| :result | ^ result do]].
   (MethodNotFound new `>> [message: message. ]) signal
].

First, the #notFoundOn: signal-handler method creates a Message  
object. Then it calls #didNotUnderstand:at: on each argument in turn  
(left-to-right precedence). If the result of sending it returns Nil,  
it continues. Otherwise, it assumes that it returns a 0-argument  
block which it then evaluates and returns, rather than continuing on  
to check further arguments or signal MethodNotFound.

The convention of Nil-vs.-0-arg-Method is arbitrary, mostly chosen  
for genericity. The other possibilities that occurred to me were:

1) Return a value, anything but Nil. The 0-arg block convention  
allows returning Nil ultimately so it's a little more generic.

2) Return a Method with the correct arity and applying it to the  
arguments as well as the optionals. This seemed too constricting,  
plus the #didNotUnderstand:at: handler already receives that  
structure so it could do that itself.

The 0-arg Method returned will likely be a Closure so it has a little  
extra overhead. Anyway, for those who are interested in this kind of  
thing, make yourself heard if there's something I'm missing as a use- 
case or whatever. Sometime, I'll get around to writing some types  
that use this, but they'll be the ones that need something more  
powerful than regular delegation.

Anyway, this solution is notable in that multiple-dispatch systems  
generally don't allow this kind of override - this is a kind of  
compromise that mostly honors the philosophy of multiple dispatch. I  
will admit that DNU-style usage of Smalltalk is usually not good  
practice (since DNU overrides do not compose safely), but there are  
valid cases for its usage.

My "blue sky" alternative is the ability to override an object's Map  
with some regular Slate object, but this is not yet feasible.

--
-Brian
http://tunes.org/~water/brice.vcf

-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : /archives/slate/attachments/20060321/4d1d324a/PGP.pgp


More information about the Slate mailing list