Blocks are:
A block is defined by [ ]
[ expressions. ... ]
( 1 / 0 )
-> Error
[ 1 / 0 ]
> [ 1 /0 ]
[ 1 / 0 ].
1 + 2
> 3
Executing a block is done explicitly through value
[ 2 + 6 ] value
> 8
[ 1 / 0 ] value
> Error
A block can take arguments (just like methods)
[ :x | x + 2 ]
[ ]
delimits the block:x
is a block argumentx + 2
is the block body[ :x | x + 2 ] value: 5
> 7
value: 5
executes the block with 5 as argumentx
is 5 during the block executionBlock execution returns the value of the last expression
[ :x |
x + 33.
x + 2 ] value: 5
> 7
| add2 |
add2 := [ :x | x + 2 ].
add2 value: 5.
> 7
add2 value: 33
> 35
Example:
[ :x :y | x + y ]
:x :y
are block arguments
How to execute a block with two arguments?
[ :x :y | x + y ] ??? 5 7
> 12
[ :x :y | x + y ] value: 5 value: 7
> 12
value: 5 value: 7
evaluates the block with 5 and 7x
is 5 and y
is 7 during the block evaluationBlocks can define temp. variables (just like methods)
Collection>>affect: anObject when: aBoolean
self do: [ :index | | args |
args := ....
aBoolean
ifTrue: [ anObject do: args ]
ifFalse: [ anObject doDifferently: args ] ].
| args |
defines a temporary variable named args
args
exists only during block evaluation
When a return ^
is executed in a block, computation exits the method defining the block
Integer>>factorial
"Answer the factorial of the receiver."
self = 0 ifTrue: [ ^ 1 ].
self > 0 ifTrue: [ ^ self * (self - 1) factorial ].
self error: 'Not valid for negative integers'
0 factorial
>1
42 factorial
>1405006117752879898543142606244511569936384000000000
[ :variable1 :variable2 ... |
| tmp |
expression1.
... variable1 ...
] value: ... value: ...
/