13.07.2015 Views

Smalltalk Best Practice Patterns Volume 1: Coding - Free

Smalltalk Best Practice Patterns Volume 1: Coding - Free

Smalltalk Best Practice Patterns Volume 1: Coding - Free

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Inject:into:You need an Enumeration that keeps a running value.How do you keep a running value as you iterate over a Collection?One of the first procedural programming patterns everyone learns is keeping a running total.1. Initialize the total2. For each element of a collection, modify the total (sum, min, max, whatever)3. Use the resultThus, you see a lot of <strong>Smalltalk</strong> code that looks like this:| max |max := 0.self children do: [:each | max := max max: each value].^maxThis is so common, in fact, that there is a message that does it for you.Why doesn’t everybody use this mysterious and powerful message? Because it has a funky name.People see the name and they think, “No way can I figure out what that does. Better leave it alone.”This is no excuse for not using it, though. When what you mean is “keep a running value over thiscollection,” you should use the message, strange name and all.Use inject:into: to keep a running value. Make the first argument the initial value. Make thesecond argument a two element block. Call the block arguments “sum” and “each”. Have theblock evaluate to the next value of the running value.The code above becomes:^self childreninject: 0into: [:sum :each | sum max: each]There is a clever use of inject:into: that I just learned. Usually I use “clever” as an insult, but I justcan’t help but show this one. The problem is iterating over adjacent pairs in a collection. That is, Iwant to evaluate some code for elements one and two, then elements two and three, and so on.Here’s how you use inject:into: for this:self childreninject: nilinto:[:eachPrevious :eachNext |eachPrevious notNil ifTrue: [...].eachNext]The first time through the loop eachPrevious is nil and eachNext is the first element of thecollection. The conditional code isn’t evaluated. The whole block evaluates to the first element ofthe collection. The second time through eachPrevious is the first element of the collection andeachNext is the second element. The conditional code gets executed. This keeps going untileachPrevious is the second to last element and eachNext is the last element.<strong>Coding</strong> <strong>Patterns</strong> page 110 of 147 9/30/2006

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!