Lade...
 

iterate

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: Iterable )
    Stack

    Stack Position Beschreibung
    Stack(In) Top ein Objekt
    Stack(Out) Top -
    Ein einzelnes Objekte, welches eine Iteration mittels der virtuellen Methode GetDataSource() definiert. Diese Methode verlangt von dem Objekt nicht, vor der Iteration die Anzahl der Iterationsdurchläufe zu kennen (Cardinality).
    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, . . ., Stmtnoder   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, . . ., Stmtnoder   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, . . ., Stmtnoder   iterate(stmtName, UNSAFE+BACKWARD) bzw.
iterate(BACKWARD+UNSAFE) { Stmt1, . . ., Stmtnoder   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).
Iterate selbst startet keine neue Transaktion!

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.