[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