Tricky Smalltalk Problem Solved

An old friend sent me a note recently asking for advice about a problem he was having with Smalltalk. He explained the situation well. It involved inconvenient binding of super in an exception handler that was providing the default behavior in a double dispatch. I didn't have a slick fix, so I had to get philosophical ...


I worked through your problem and see what is going wrong. I haven't faced the same thing and solved it so I have nothing clever to offer. I have found my self caught in similar fixes and here is what I've learned:

You know, I've also found that I can impress beginners by dragging out one of Smalltalk's neat little features. But, to impress Smalltalk pros I have to show them a clever use of plain old objects.

I hope this helps should you have to yank the machinery and replace it with something that, at first, seems stupid and repetitive.

-- WardCunningham


This sounds a place to apply a pattern I have I'll call "Refactor Problem Expressions".

I assume, from your description, that the problem method contains an expression like:

"..."
super doSomethingWith: anArgument.
"..."
and "super" is binding to an inconvenient receiver.

I like to replace the "super" with an indirection, like this:

"..."
self doubleDispatcher doSomethingWith: anArgument
"..."

Now, the implementation of "doubleDispatcher" can be experimented with until you like it. Of course, there is probably a better name than "doubleDispatcher" that you can use.

The point of the pattern is to isolate the problem in its own method that you can hack on while you find your favorite implementation.

Furthermore, the existence of this problem usually means that the original expression is hard for a reader to understand.

So I might refactor again, into something like this:

"..."
self doubleDispatchWith: anArgument.
"..."

and put this indirection in the "doubleDispatchWith:" method, like this:

doubleDispatchWith: anArgument
    ^self doubleDispatcher doSomethingWith: anArgument

Now, you can rename "doubleDispatchWith:" into something that names the operation you were trying to do, and the code becomes even easier to read.

Most of the time, I find that the "extra" indirections have, in fact, helped me identify and provide the seams and hooks that should have been in the original method.

-- TomStambaugh


EditText of this page (last edited January 3, 1996) or FindPage with title or text search