This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: More to Understand:
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
I thought I'd do a week's recap and sum up here today.
Other Uses
There's actually lots of other examples of things you can do with doesNotUnderstand: Most of my examples have revolved around "extending" the semantics of selectors. But there's other things you can do:
Proxies: You can of course do the classical Proxy thing. You can find an example of this in the package Weaklings. It has a WeakProxy object. I thought there was an example in the base too, but I'm not seeing it. If you have OpenTalk loaded, you'll of course find good proxy examples there too.
More Interpreted Selector Examples: Michael Lucas-Smith has (at least) two such packages in the Open Repository: XMLMaker and HigherOrderMessages. The first allows you to tersely construct XML/HTML via normal method selector patterns. The other allows patterns such as "coll select: [:each | each name first = $A]]" to be expressed simply as "coll select name first = $a".
Examples In the Base: Implementors of doesNotUnderstand: in a VW7.2 image with Store and the RB loaded show that there are no less than 9 implementations besides the one in Object. Some are from "Old Browsers", but others come out of some of the newer stuff (most look to be of the "forwarder" pattern, which is what Monday's blog was an example of). RTP has 4.
Message Eating nil: Nevin Pratt wrote an excellent article about implementing doesNotUnderstand: for nil, like Objective-C does.
What have I missed: I'm sure there are other good examples, throw a comment in for those I've missed.
Response to a Response
David Buck wrote an excellent response to one of my DNU: blogs. I think I agree pretty much with David and I'm glad he took the time to respond. I operate in different environs than David does, so naturally, he and I might give different weights to some of the points.
David lists 11 things that one really ought to be aware of when playing with dnu: I would characterize most of them as "the tools aren't prepared for this." Which is fine. The question comes down to: where's the real value, in the Smalltalk system itself, or the IDE? I believe both, and that there's a great synthesis between the two, but I won't be slave to one or the other. You have to weigh out, on a case by case basis, how much value you'll get from a DNU: override versus some trickery the tools do.
Some Smalltalks (Dolphin and VA when I used them a long time ago), don't use the currently interned Symbol set to be a reflection of implemented messages. Doing so in VisualWorks is really nice, but lets take it with a grain of salt. It can tell you a message exists that doesn't really (i.e. somebody used the symbol #intialize in their model, but there is no message that implements it). The technique of splicing selectors, a questionable, but sometimes very useful practice, also gives the tools fits.
That you will find no implementors of with:* is kind of the point. There aren't any. They're runtime determined macros. With the technique shown Thursday, you can even make the debugger look sane pretty easily. The one that would bother me the most is the comment David added to the isotropic selectors one, that points out that method renaming is going to get difficult.
doesNotUnderstand: is implemented pretty efficiently for VisualWorks, but we are doing work in Smalltalk to figure out what message(s) to send by examining them. So we're obviously going to pay a speed penalty for this kind of stuff. Again, the context is important.
That the context is important is probably best exemplified by OpenTalk proxies. The same 11 arguments all exist there. But if you're interested in doing distributed OO, suddenly you can live with the tools that don't get it because not all message signatures are local, the fact that debugger's a bit more of a ride, the hit in performance, etc.