Handling doesNotUnderstand in Jtalk
Until now, Jtalk didn't support "#doesNotUnderstand:", mostly because Smalltalk message sends were compiled into JavaScript function calls like this: "self foo: anObject -> self.foo(anObject);". While this approach is the best solution in term of speed, it has several inconvenients:
- It doesn't allow sending messages to the "undefined" object;
- It makes support for "#doesNotUnderstand:" almost impossible.
The first one is probably the most problematic issue, but being able to handle "#dnu:" may be very interesting too, when implementing proxies for example. The master branch on Github now includes support for handling "#dnu" and sending message to "undefined" using decoupled message sends. Here's how it works:
st.send = function(receiver, selector, args) {
if(typeof receiver === "undefined") {
receiver = nil;
}
if(receiver[selector]) {
return receiver[selector].apply(receiver, args);
} else {
return messageNotUnderstood(receiver, selector, args);
}
};
First, if the receiver is "undefined", it will use to the Smalltalk "nil" object instead. Then if the receiver can understand the selector, the corresponding function is called, else the `#doesNotUnderstand:` message will be sent to the receiver, triggering an error by default. The Smalltalk counterpart is very simple, and any subclass interested in handling `#dnu:` differently might override the method.
Object >> doesNotUnderstand: aMessage
MessageNotUnderstood new
receiver: self;
message: aMessage;
signal
Sure, this has a runtime cost. But I'm not that much interested into speed for now, optmizations will come later. Anyway on my laptop Jtalk is able to send 350 000 messages per second in Google Chrome.