[Squeak-ev] [Newbie] loop-Konstrukt

Bert Freudenberg bert at impara.de
Die Nov 15 11:37:06 UTC 2005


Am 15.11.2005 um 09:58 schrieb Enrico Schwass:

> Moin
>
> Im Netz habe ich eine recht gute Zusammenfassung der Squeak-Iteratoren
> gefunden. Mir fiel aber auf, das eine Art "loop"-"break" nicht
> aufgeführt ist. Hier mal als Pseudo-Code fuers Lesen einer Textdatei.
>
> ios := FileStream...
> ...
> loop: [
>   counter := counter + 1.
>   char := ios next.
>
>   (char = nil) iftrue: break.
>   (char = '\n') iftrue: break.
>   (counter > 255) iftrue: break.
>
> ]
>
> Gibts das so nicht? Mit whileTrue: liesse sich das schöner loesen??
> Ganz so heimisch fuehle ich mich in Smalltalk noch nicht :/

Merkt man - du versuchst gerade, das Problem mit der "guten alten"  
Spaghetti-Code-Methode anzugehen.

Ein "break" ist nichts weiter als ein GOTO *hinter* das Ende der  
Schleife, stimmt's? Du willst also aus einem Block (das Objekt, das  
du mit "[...]" erzeugst) hinter den Message-send von #loop: springen.  
Dieser Block wird aber wo ganz anders abgearbeitet, nämlich tief  
verschachtelt unten in der #loop:-Methode.

*Wenn* man das unbedingt will, gibt es natürlich Möglichkeiten, um  
über mehrere Ebenen der Aufrufkette zurückzuspringen: nicht-lokale  
Returns, und Exceptions. Ein nicht-lokales Return ist eins, das nicht  
frei am Ende der Methode, sondern in einem Block steht (also z.B. in  
einem von deinen #ifTrue:-Zweigen). Exceptions sollten klar sein, die  
sind prinzipiell wie in anderen Sprachen auch. Damit könnte man also  
das Break nachbauen:

| n |
n := 0.
(1 to: 10) loop: [:i | i even ifTrue: [n := i. self loopBreak]].
n "ergibt 2"

=========

loop: aBlock
	^ [self do: aBlock] on: LoopBreak do: [:ex | ex return]

loopBreak
	^LoopBreak signal

=========

Der vollständige Code ist im Anhang.

Aber das macht man normalerweise nicht. Höchstens um zu  
demonstrieren, wie einfach es ist, in Smalltalk neue  
Kontrollstrukturen einzubauen ;-)

Was genau versuchst du denn eigentlich, da zu tun? Sieht aus wie der  
Versuch, Low-Level-C++-Code eins-zu-eins nach Smalltalk zu portieren.  
Es gibt sicher einen eleganteren Weg.

- Bert -

-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : Bert-LoopBreak-bf.1.mcz
Dateityp    : application/octet-stream
Dateigröße  : 1281 bytes
Beschreibung: nicht verfügbar
URL         : http://lists.squeakfoundation.org/pipermail/squeak-ev/attachments/20051115/852bad4b/Bert-LoopBreak-bf.1.obj
-------------- nächster Teil --------------