Control flow of looping
Tim Olson
tim at jump.net
Sat Apr 13 14:08:33 UTC 2002
>Kamil Kukura <kamk at volny.cz> writes:
>
>> Is it possible in loops such as "true-or-false whileTrue: [ block ]" do
>> the iteration repeat or break out similiar to 'break' and 'continue'
>> keywords in C?
Martin Drautzburg wrote some good advice about breaking methods up into
smaller ones, and looking at the collection iteration methods
(collect/select/detect).
But since Smalltalk control flow constructs are written in Smalltalk, it
is definitely possible to create a breakable/continuable while loop
control structure.
The following examples aren't recommended for actual use, just as
examples of how you can extend Squeak's control flow constructs directly
in Squeak.
One way is to create return and continue blocks which are passed in to
the loop as arguments.
For example, adding the following two methods to the BlockContext class:
----
breakableWhileTrue: aBlock
| returnBlock |
returnBlock := [:result | ^ result].
self whileTrue: [self continuableWhileTrue: aBlock returnBlock:
returnBlock]
continuableWhileTrue: aBlock returnBlock: returnBlock
| continueBlock |
continueBlock := [^ self].
^ aBlock value: returnBlock value: continueBlock
----
allows you to write loops like:
n := 0.
m := 0.
[n := n + 1. n < 50] breakableWhileTrue: [:return :continue |
n > 10 ifTrue: [return value: m].
n odd ifTrue: [continue value].
m := m + 1].
Another way is to piggyback on the powerful exception handling
capabilities exisiting in Squeak. You can define two new Exception
subclasses: LoopExit and LoopContinue. Then add a new loop method to
BlockContext:
breakableWhileTrue: aBlock
self whileTrue:
[[[aBlock value: LoopExit value: LoopContinue]
on: LoopExit do: [:ex | ^ ex messageText]]
on: LoopContinue do: []]
Then your loop would look like:
n := 0.
m := 0.
[n := n + 1. n < 50] breakableWhileTrue: [:return :continue |
n > 10 ifTrue: [return signal: m].
n odd ifTrue: [continue signal].
m := m + 1].
-- tim
More information about the Squeak-dev
mailing list
|