Normally we use for loops without thinking about what goes on behind the scenes. In this case we have an array, and we're iterating over the array. But the for-loop is actually calling list._Enum(). So if you replace the line for letter in list with for letter in list.__Enum() it does the same thing.
Code: Select all
list := ['A', 'B', 'C']
for letter in list
MsgBox letter
Code: Select all
for i in constant
MsgBox i
constant(&var) => (var := 42)
The for-loop then determines whether it should finish or keep going. This is determined by the return value of the enumerator object. Since the last line is var:=42, and 42 evaluates as True, the loop will continue forever.
How to write enumerators by dividing them into 3 sections.
Let's write a counting function.
Code: Select all
nat() {
; Constants
start := 0
enumerate(&n) {
n := start ; yield statement
start += 1 ; do block
return True ; continue?
}
return enumerate
}
for n in nat()
MsgBox n
The do block is where things happen. In this case we are incrementing start. Why not increment n directly? It wouldn't work because then the function would only return 1 continuously by adding 1 to start.
The last line of the function should always be a boolean. It can be a condition that needs to be evaluated.
This counting function prints out 2, 3, 4.
Code: Select all
range(start, stop) {
; Constants are start and stop.
enumerate(&n) {
n := start ; yield statement
start += 1 ; do block
return n < stop ; continue?
}
return enumerate
}
for n in range(2, 5)
MsgBox n
The yield statement yields start as the first value.
The do block increments start by 1.
The continue? expression evaluates whether n is currently less than 5. If it is, it will return false, ending the for-loop.
Enumerate the characters of a string.
Code: Select all
str(s) {
pos := 1
enumerate(&char) {
char := SubStr(s, pos, 1) ; yield statement
pos++ ; do block
return pos-1 <= StrLen(s) ; continue?
}
return enumerate
}
for char in str("kangaroo")
MsgBox char
The yield statement yields the first letter of the string.
The do block increments the position by 1.
The continue? expression evaluates whether the position has reached the end of the string.
In this example, the do block and continue could be combined as pos++ <= StrLen(s).
Hopefully now enumerators won't be a mystery anymore, and you will be able to write your own.