iterate
iterate { Stmt1, . . ., Stmtn } oder iterate(prozedurName) (veraltet)
Der auf iterate folgende Anweisungsblock bzw. die im Parameter angegebene Prozedur wird iterativ ausgeführt. Die Anweisung "zerlegt" den auf dem Stack vorgefundenen Wert in seine Elemente. Für jedes Element werden die von dem iterate-Statement kontrollierten Anweisungen aufgerufen. Das jeweils aktuelle Element liegt zu Beginn eines Durchlaufs auf dem Stack.
- Die Anzahl der Elemente bestimmt die Anzahl der Zyklen.
- Für jeden Zyklus wird das aktuelle Element auf den Stack gebracht.
- Im k-ten Zyklus erhält man die Zahl k mit Anweisung Index
- Die Iteration bricht vorzeitig ab, wenn in der Anweisungsfolge ein break-Statement erreicht wird; d. h. dann wird mit der auf das iterate-Statement folgenden Anweisung fortgesetzt.
- Anweisung continue beginnt den nächsten Iterationszyklus, springt also zum Anfang der Anweisungsfolge (Beispiel).
- Eine Collection oder ein Vektor (Ausnahme List-Widgets s. u.) dürfen während der Iteration modifiziert werden; die Änderungen sind ohne Einfluss auf die Iteration (os_cursor::update_insensitive - siehe ObjectStore Dokumentation, bzw. bei Vektoren wird eine Kopie erstellt). Wird eine Collection während der Iteration verändert (erweitert/geleert), sollte man stattdessen mit einem Cursor durch die Collection iterieren.
Iteration ist möglich über
- eine Collection
Stack Stack Position Beschreibung Stack(In) Top eine Collection Stack(Out) Top - Für jedes Element der Collection werden die der Iteration unterworfenen Anweisungen ausgeführt.
Address-Space Überlauf kann nicht behandelt werden und führt in jedem Fall zum Abbruch - ein Ausweg besteht darin, dass man auf die Veränderbarkeit der Collection verzichtet: iterate(UNSAFE). - eine Collection mit Index-Pfad
Stack Stack Position Beschreibung Stack(In) Top ein Indexpfad Top-1 eine Collection Stack(Out) Top - Der auf Stack-Top liegende Indexpfad (vergleiche Anweisung IndexPath) steuert die Reihenfolge der Iteration über die Collection.
Address-Space Überlauf kann nicht behandelt werden und führt in jedem Fall zum Abbruch - ein Ausweg besteht darin, dass man auf die Veränderbarkeit der Collection verzichtet: iterate(UNSAFE). - ein Windowobjekt ObjectBoxen, ObjectCombobox
Stack Stack Position Beschreibung Stack(In) Top eine Objektbox Stack(Out) Top - Oben genannte Windowobjekte können als visuelle Repräsentation einer Collection angesehen werden, und, in Analogie zum ersten Fall, wird hier die Anweisung für jedes von der Objektbox visualisierte Objekt aufgerufen. Widget bringt eine Objektbox auf den Stack.
Im Gegensatz zur Iteration über eine Collection dürfen während der Iteration über eine ObjectList keine Objekte in die ObjectList eingefügt oder daraus entfernt werden.
Address-Space-Überlauf wird vom ClassiX®-System behandelt. - einen Vektor
Stack Stack Position Beschreibung Stack(In) Top ein Vektor Stack(Out) Top - Über alle Elemente des Vektors wird iteriert.
Der Vektor darf modifiziert werden, d. h. es wird über eine Kopie des Vektors iteriert. Wenn der Vektor unverändert bleibt, sollte man diesen Aufwand sparen und iterate(UNSAFE) benutzen.
Address-Space-Überlauf wird vom ClassiX®-System behandelt.
Eine weitere Form der Iteration über ein Vektor ist:Stack Stack Position Beschreibung Stack(In) Top Top-1 Elementn ... . . . Top-n Element1 Top-(n+1) Stack(Out) - wobei es keinen Unterschied zwischen iterate und iterate(UNSAFE) gibt, da der Vektor im Iterationszyklus nicht mehr modifiziert werden kann.
Address-Space-Überlauf wird vom ClassiX®-System behandelt.Ein Vektor wird standardmäßig rückwärts durchlaufen, mit BACKWARD vorwärts.
Code-Beispiel:
[ 1€ 2€ 3€ ] iterate { Attention } => 3€ Attention, 2€ Attention, 1€ Attention - ein Objekt
Stack Stack Position Beschreibung Stack(In) Top ein Objekt Stack(Out) Top - Ein einzelnes Objekt definiert mittels der virtuellen Funktionen GetIndexedCount(), ob eine Iteration über irgendwelche Elemente dieses Objekts definiert ist (Beispiel: CX_CONDITIONED_BAG - Elemente sind die CX_FCONDITION-Objekte; Iteration über COM-Objekte).
Andernfalls wird das Objekt wie eine Collection behandelt, das nur dieses Objekt als Element enthält, d. h. es gibt nur einen Iterationszyklus.
Rückwärts-Iteration ist nicht möglich.Address-Space-Überlauf wird nicht vom ClassiX®-System behandelt - führt also in jedem Falle zum Abbruch.
-
ein iterierbares Objekt (Symbol: )
StackStack Position Beschreibung Stack(In) Top ein Objekt Stack(Out) Top -
Beispiel: -
Var(file) CreateTransObject(CX_ASCII_FILE) -> file
"CX_SYSTEM_OUT/inputfile.txt" file Put(fileName)
file iterate {
LocalVar(recordVector, value) -> recordVector
0 recordVector GetElement -> value //Erstes Feld des Records
value "break" = if { break } //Iteration vorzeitig abbrechen, wenn das Wort "break" gelesen wird
} - eine multilinguale Zeichenkette (multiple string)
Stack Stack Position Beschreibung Stack(In) Top multiple string Stack(Out) Top Im Zyklus k liegt die k-te Teilzeichenkette auf dem Stack. Während der Iteration darf die Zeichenkette nicht verändert werden.
Address-Space-Überlauf wird nicht vom ClassiX®-System behandelt - führt also in jedem Falle zum Abbruch.
iterate(BACKWARD) { Stmt1, . . ., Stmtn } oder iterate(stmtName, BACKWARD)
Parameter: Name einer Anweisung
Iteration in umgekehrter Reihenfolge. Rückwärtsiteration ist für alle oben aufgeführten Varianten definiert. Eine Ausnahme bildet die Iteration über ein einzelnes Objekt
iterate(UNSAFE) { Stmt1, . . ., Stmtn } oder iterate(stmtName, UNSAFE)
Parameter: Name einer Anweisung
Iteration über eine Collection definiert mit iterate(UNSAFE):
In diesem Modus darf die Collection nicht verändert werden.
Der Vorteil: Address-Space-Überlauf kann vom ClassiX®-System automatisch behandelt werden.
Iteration über einen Vektor mit iterate(UNSAFE):
Der Vektor darf während der Iteration nicht verändert werden.
Der Vorteil: Performancegewinn (Beispiel).
Address-Space-Überlauf wird für beide Formen vom ClassiX®-System behandelt.
iterate(UNSAFE+BACKWARD) { Stmt1, . . ., Stmtn } oder iterate(stmtName, UNSAFE+BACKWARD) bzw.
iterate(BACKWARD+UNSAFE) { Stmt1, . . ., Stmtn } oder iterate(stmtName, BACKWARD+UNSAFE)
Parameter: Name einer Anweisung
Rückwärtsiteration über eine Collection, wobei auf die Veränderbarkeit der Collection verzichtet wird. Damit wird die Behandlung von Address-Space-Überlauf durch das ClassiX®-System möglich.
Rückwärtsiteration über einen Vektor - der während der Iteration unverändert bleiben muss - mit Performancegewinn.
Anweisung EndTXN innerhalb eines Iterationszyklus: Wird über eine Collection mit persistenten Elementen¹) iteriert, so muss das Weiterrücken zur nächsten Position innerhalb einer Transaktion geschehen. Des Weiteren darf EndTXN nur in Verbindung mit iterate(UNSAFE) benutzt werden, niemals innerhalb einer normalen Iterate-Schleife! Wird die Transaktion innerhalb von Iterate(UNSAFE) mit Anweisung EndTXN explizit beendet, so muss vor dem Ende des Zyklus wieder eine neue Transaktion gestartet sein (implizit durch eine auf das Objekt zugreifende Anweisung oder explizit mit BeginTXN). Weitere Hinweise geben die folgenden Beispiele ... ¹) die Collection selbst mag transient oder persistent sein |
Bei der Iteration über persistente Objekte, die in einem Vektor zusammengefasst sind, wird für das Weiterrücken zum nächsten Element keine Transaktion benötigt; nach EndTXN innerhalb des Zyklus kann man sich darauf verlassen, dass eine neue Transaktion automatisch gestartet wird, bevor ein Zugriff auf ein persistentes Objekt erfolgt.