Blocks and Iterators
Parameter-passing a block to be a closure:
"remember a block." remember := . "When the time is right -- call the closure!" remember value: 'world' "=> 'Hello, world!'"Returning closures from a method:
Integer extend [ asClosure [ | value | value := self. ^{ . } ] ] blocks := 10 asClosure. setter := blocks first. getter := blocks second. getter value "=> 10" setter value: 21 "=> 21" getter value "=> 21"Using block to send info back to the caller:
Integer extend [ ifEven: evenBlock ifOdd: oddBlock [ ^self even ifTrue: ifFalse: ] ]Invoke the above method, passing it a block:
10 ifEven: ifOdd: "=> 5"Iterating over enumerations and arrays using blocks:
array := #(1 'hi' 3.14) array do: "=> 1" "=> hi" "=> 3.14" (3 to: 6) do: "=> 3" "=> 4" "=> 5" "=> 6"A method such as inject:into: can accept both a parameter and a block. It iterates over each member of a list, performing some function on while retaining an aggregate. This is analogous to the foldl function in functional programming languages. For example:
#(1 3 5) inject: 10 into: "=> 19"On the first pass, the block receives 10 (the argument to inject) as sum, and 1 (the first element of the array) as element, This returns 11. 11 then becomes sum on the next pass, which is added to 3 to get 14. 14 is then added to 5, to finally return 19.
Blocks work with many built-in methods:
(File name: 'file.txt') withWriteStreamDo: [ :file | file nextPutAll: 'Wrote some text.'; nl ] "File is automatically closed here" (File name: 'file.txt') linesDo: [ :each | each displayNl ] "=> Wrote some text."Using an enumeration and a block to square the numbers 1 to 10:
(1 to: 10) collect: "=> "Read more about this topic: GNU Smalltalk, Examples
Famous quotes containing the word blocks:
“Good blocks of oak it was I split,
As large around as the chopping block;
And every piece I squarely hit
Fell splinterless as a cloven rock.”
—Robert Frost (18741963)