This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: withWithWithWith... style
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
The base image comes with 4 variants of the with:+ message implemented on 3 collection classes (Collection, ArrayedCollection, MappedPalette).
What happens when you need 5? Many add a with:with:with:with:with message. Most will notice that they need to clone the 4 argument version in both Collection (uses add:) and ArrayedCollection (uses at:put:). Key has such an extension; I've seen sites that have up to 7 (what's the highest you've seen?). One thing I did not catch, was that this allows MappedPalette to respond to the 5 arg version, but not having its own implementation, it fails. But I digress.
The other day, I turned to the nameles one next to me and said, "I need 6." Some shy at these ad-with:eam messages. It just feels wrong in some cases to see code like this. One place that I feel it is legitimately handy though is in tests. And I write lots of those.
The more I thought about the pattern, I realized this is just varargs (varargs is the C languages ability to specify a function(a,b,....) where the .... denotes a variable number of arguments). It's nice to be able to specify a collection from a vararg like construct. We don't have such a syntax in Smalltalk. And I'd hate to see one added.
So I implemented this message on the class side of Collection.
isRepeatedWiths: aSelector
aSelector runsFailing: [:each | each = $:]
do: [:run | run = 'with' ifFalse: [^false]].
^true
This is really cool, I think. I no longer need with: in my system. Nor do I need with:with:. Or the 3, 4 versions. Or our 5 arg one. Or the looked for 6 one. I've replaced 3 x 5 messages with 1. And when I need 9 with:'s, it'll just work. Basically we've created a vararg message selector pattern for Collection creation. For MappedPalette, one has to implement withAll: which forrwards to withColors: (this seems like an oversight on the base image's part).
Notice that we don't even send a multi arg message, we just use aMessage's arguments lists. We've made this pattern build upon withAll:, so adding new types of collection to the system, you just have to make sure that one method is implemented appropriately, no need to worry about overriding all of the with: variants. Collection, by questioning what he doesn't understand, is all the more useful.