Previous: Intervals, Up: Code blocks (II)
Let us revisit the checking example and add a method for scanning only checks over a certain amount. This would allow our user to find “big” checks, by passing in a value below which we will not invoke their function. We will invoke their code block with the check number as an argument ment; they can use our existing check: message to get the amount.
Checking extend [ checksOver: amount do: aBlock history keysAndValuesDo: [:key :value | (value > amount) ifTrue: [aBlock value: key] ] ]
The structure of this loop is much like our printChecks message sage from chapter 6. However, in this case we consider each entry, and only invoke the supplied block if the check’s value is greater than the specified amount. The line:
ifTrue: [aBlock value: key]
invokes the user-supplied block, passing as an argument the
key, which is the check number. The value:
message, when received by a code block, causes the code
block to execute. Code blocks take value
, value:
,
value:value:
, and value:value:value:
messages, so you
can pass from 0 to 3 arguments to a code block.33
You might find it puzzling that an association takes a
value
message, and so does a code block. Remember, each
object can do its own thing with a message. A code block gets
run when it receives a value
message. An association merely
returns the value part of its key/value pair. The fact that
both take the same message is, in this case, coincidence.
Let’s quickly set up a new checking account with $250 (wouldn’t this be nice in real life?) and write a couple checks. Then we’ll see if our new method does the job correctly:
mycheck := Checking new. mycheck deposit: 250 mycheck newChecks: 100 count: 40 mycheck writeCheck: 10 mycheck writeCheck: 52 mycheck writeCheck: 15 mycheck checksOver: 1 do: [:x | x printNl] mycheck checksOver: 17 do: [:x | x printNl] mycheck checksOver: 200 do: [:x | x printNl]
We will finish this chapter with an alternative way of
writing our checksOver:
code. In this example, we will use
the message select:
to pick the checks which exceed our
value, instead of doing the comparison ourselves. We can
then invoke the new resulting collection against the user’s
code block.
Checking extend [ checksOver: amount do: aBlock [ | chosen | chosen := history select: [:amt| amt > amount]. chosen keysDo: aBlock ] ]
Note that extend
will also overwrite methods. Try
the same tests as above, they should yield the same result!
There is also a valueWithArguments:
message
which accepts an array holding as many arguments
as you would like.
Previous: Intervals, Up: Code blocks (II)