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.

Nicolas Petton , the 03 May 2011
blog comments powered by Disqus