This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: Let's Lookup another Collection of Extensions
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
Thursday's blog a little late here. Playing catchup.
One day, a while back, I had put together a "model" of some real world phenomena that I was pasting a UI on top of. Part of it was a pretty simple thing where an Array did the model well. There was a bit of code where the index of the elements was important too.
Then they pulled a fast one on me: "sometimes, it's possible for one of the intermediate slots to just not be there." I sighed. Noodled for a little bit. And then decided to just use a Dictionary with Integer lookup keys. Doing so was kind of enlightening; I suddenly thought about the problem with a higher level of APIs, things like keysAndValuesDo:, etc. At this point, it donned on me that SequenceableCollections (or Sequences for short) are just Dictionaries with specialized key domains. Adding a variety of the dictionary APIs to Sequence enables more mental tools to use on your model. And that's one of the things Smalltalk is all about: giving you the programmer better tools to bridge the way your brain wants to model problems with the way the computer does. The following methods (and tests) should be self explanatory, because they all come from Dictionary.
at: aKey ifPresent: aBlock
| val |
val := self at: aKey ifAbsent: [^nil].
^aBlock value: val
Honorable Mention
keysAndValuesDo: aBlock
"Evaluate aBlock with each of the receiver's key/value pairs
(e.g. indexes and elements) as the arguments."
1 to: self size do: [:i | aBlock value: i value: (self at: i)]
Wait a minute, that's not an extension! That's in the base! Well it is since 7.0. I submitted it then; it was the original inspirator for the rest of these. I wish that it's siblings would make it into the base as well.
The Tests
testGenericAtIfAbsent
| a |
a := (11 to: 20) asArray reverse.
self
assert: (a at: 3 ifAbsent: [#hi]) = 18;
assert: (a at: -1 ifAbsent: [#hi]) = #hi;
assert: (a at: 20 ifAbsent: [#hi]) = #hi