The Loop
command is a very flexible, powerful method of handling any type of repeating structure. It can iterate through Arrays, or repeat a set number of times, or even just repeat indefinitely until told to quit. In each case, the data between the opening Loop
command and the corresponding EndLoop
command that closes it is repeated as many times as is appropriate.
There are five commands that belong to the Loop
family - Loop
, EndLoop
, Break
, Continue
, and SetLoop
. Each Loop
command has to have a corresponding EndLoop
command, and the other commands should appear between them, if and when required.
The Loop
, Break
, Continue
, and SetLoop
commands consist of the command followed by an expression. The EndLoop
command does not use an expression, and so will ignore any expression given. Break
, Continue
, and SetLoop
expect the expression to evaluate to an integer Number, and the Loop
expression can take various different forms depending on the desired behaviour.
The magic Constant __CurrentLoop__
can be used to access the current iteration number.
There are five alternate syntaxes for the Loop
command:
loop
loop a
loop a as v
loop a as k: v
loop a as k:
The first, simplest syntax repeats indefinitely, until the structure is exited using a Break
command.
For example:
{ loop }… { if __CurrentLoop__ > 3 }… { break }… { endif }… { __CurrentLoop__ } { endloop }
1
2
3
The next syntax allows an Array to be iterated through, in a very simple manner. Generally this is an easy way to loop through an Array structure that consists of a main Array containing several sub-Arrays of data, such as results from a database. The current Array key can be accessed through the __CurrentLoop__
magic constant if necessary, or else the Double-dot shortcut Operator can be used.
For example:
{ Users = [ ["Forename": "John", "Surname": "Smith"], ["Forename": "Billy", "Surname": "Jones"] ] }… { loop Users }… { Users..Forename // Same as saying Users.__CurrentLoop__.Forename, but shorter! } { endloop }
John
Billy
The example above demonstrates a common use of the Double-dot Operator, combined with a straightforward and simple Loop
syntax. However, using __CurrentLoop__
is not always appropriate.
For example:
{ loop 5...7 }… { __CurrentLoop__ } { endloop }
0
1
2
In this example, the intention would probably be to loop through 5, 6, 7. However, the Array created by the Range Operator contains these numbers as item values, and the item keys are 0, 1, 2.
The remaining three syntaxes allow an Array to be iterated through in the same manner as the last method, but allow the current value and/or key of the Array to be assigned to a specified Variable. This can be used to simply save using the __CurrentLoop__
magic constant, or it can be used to directly manipulate the Array contents.
For example:
{ Users = [ ["Forename": "John", "Surname": "Smith"], ["Forename": "Billy", "Surname": "Jones"] ] }… { loop Users as User }… { User.Forename } { endloop }
John
Billy
{ loop 5...7 as v }… { v } { endloop }
5
6
7
{ loop 5...7 as k: v }… { k ~ ": " ~ v } { endloop }
0: 5
1: 6
2: 7
{ loop 5...7 as k: }… { k } { endloop }
0
1
2
Loop
structures can be nested indefinitely within other Loop
structures, and within other command structures.
The Break
command allows Loop
execution to be cut short and quit at any point. If an expression is supplied, it is expected to be numeric, and determines how many nested loops are to be broken out of (1 by default).
For example:
{ loop 14...19 as i }… { if i > 16 }… { break }… { endif }… { i } { endloop }
14
15
16
The Continue
command cuts execution of the current loop short, skips the remainder of the loop, and starts the next one. If an expression is supplied, it is expected to be numeric, and determines how many nested loops are to be continued (1 by default).
For example:
{ loop 1...3 }… Outer { loop }… Middle { loop }… Inner { continue 3 }… { endloop }… This gets skipped { endloop }… This also gets skipped { endloop }
Outer Middle Inner Outer Middle Inner Outer Middle Inner
The SetLoop
command sets the value of the current loop, as given by the __CurrentLoop__
magic constant. It is most useful within a loop of indefinite repetition, as any of the other Loop
constructs will overwrite the value again every time a fresh loop is started.
For example:
{ loop }… { if __CurrentLoop__ > 5 }… { break }… { endif }… { if __CurrentLoop__ == 3 }… { setloop 4 }… { endif }… { __CurrentLoop__ } { endloop }
1
2
4
5
In any form of the Loop
construct, the current loop identifier (generally a Number, but possibly a String if looping through an Array) can be accessed by using the magic constant __CurrentLoop__
, or in some situations, the Double-dot Operator, which is its shortcut.
However, that only works for the innermost Loop
in a nested situation. In this case, the complementary magic constant __CurrentLoops__
can be used. __CurrentLoops__
is an Array containing all of the current loop identifiers of the nested structure, with the outermost loop as index 0
.