GNU Smalltalk - Examples - Blocks and Iterators

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 (1874–1963)