I did another pass on the Block chapter I'm writing and I would like to know
if I'm not saying something wrong.
Here is what I wrote.
The following examples shows that escaping blocks jumped to their home context
but do not unwind the stack after this point.
\ct{valueWithExit} is defined on the class BlockClosure as follows.
\begin{code}{}
BlockClosure>>valueWithExit
self value: [ ^nil ]
\end{code}
\begin{code}{}
BExp>>assert: aBoolean
aBoolean ifFalse: [Error signal]
BExp>>testValueWithExitBreak
| val |
[ :break |
1 to: 10 do: [ :i |
val := i.
i = 4 ifTrue: [break value].
]
] valueWithExit.
self assert: val = 4.
\end{code}
\ct{testValueWithExitBreak} shows that the block \ct{break} is created and
activated once and as effect it cancels the rest of the computation.
The following method \ct{testValueWithExitContinue} shows that just the
computation left from the block activation is skipped (here \ct{val := val + 1.
last := i}, when i = 4) and this is why the value of \ct{val} is 9 and not 10.
In this example, a new block is created
\begin{code}{}
BExp>>testValueWithExitContinue
| val last |
val := 0.
1 to: 10 do: [ :i |
[ :continue |
i = 4 ifTrue: [continue value].
val := val + 1.
last := i
] valueWithExit.
].
self assert: val = 9.
self assert: last = 10.
\end{code}
Pay attention here \ct{valueWithExit} is not equivalent to \ct{value: [^nil]}
because it changes the home context of the block.
In the first case the homeContext of the block is not the method
\ct{testValueWithExitContinue} while in the second it is.
Put a self halt before the assert: to convince you. In one case, you will reach
the halt while in the other not.