blob: 5740f3771ddfc66a45badb86db8164698d8da536 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001NAME
2 foreach
3
4SYNTAX
5 foreach (<var> : <expr>) <statement>;
6 foreach (<var>, <var2>, ... ,<varN> : <expr>) <statement>;
7
8 foreach (<var> : <expr1> .. <expr2>) <statement>;
9 foreach (<var>, <var2>, ... ,<varN> : <expr1>..<expr2> ) <statement>;
10
11 /* MudOS compatibility only - not for new code: */
12 foreach (<var> in <expr>) <statement>;
13 foreach (<var>, <var2>, ... ,<varN> in <expr>) <statement>;
14
15DESCRIPTION
16 The instruction evaluates its range specification - either a
17 simple <expr> which can yield an array, a struct, a string, a
18 mapping or an integer, or an integer range <expr1> through
19 <expr2> - and executes <statement> once for each value in the
20 range. The respective value is assigned to <var> right before
21 <statement> is executed.
22
23 A 'break' in the <statement> will terminate the loop. A
24 'continue' will continue the execution from the beginning of
25 the loop.
26
27 Every <var> specification can declare a new local variable, whose
28 scope is the whole foreach() statement.
29
30
31 The normal form (one <expr>):
32
33 <expr> is evaluated and has to yield an array, a struct, a
34 string or a mapping (or reference to the former), or an
35 integer.
36
37 If <expr> is a array, struct, or string, the values of
38 <expr> (in case of the string, the integer values of the
39 characters) are then assigned one by one in order of
40 occurence to <var>, and <statement> is executed for every
41 assignment.
42
43 If <expr> is a mapping, the keys are assigned one by one
44 to <var>, and the values for each key are assigned in
45 order to <var2>..<varN>. If there are more values than
46 variable, the extraneous values are ignored. Due to the
47 nature of mappings, a specific order of the keys can not
48 be guaranteed.
49
50 If <expr> evaluates to a reference to an array, mapping, or
51 string, the loop will assign references to the values into
52 the variables. This allows the loop body to change the contents
53 of the original data.
54
Zesstra3085c662025-08-02 18:31:10 +020055 If <expr> evaluates to an integer, the loop will count up <var>
MG Mud User88f12472016-06-24 23:31:02 +020056 from 0 to <expr>-1, basically implementing a count loop.
57
Zesstra3085c662025-08-02 18:31:10 +020058 If <expr> evaluates to a coroutine, the loop will call the
59 coroutine until the coroutine finishes execution. All values
60 from the coroutine's yield() calls will be assigned to <var>,
61 essentially using the coroutine as a generator function.
62
MG Mud User88f12472016-06-24 23:31:02 +020063 If there are more variables than necessary, the unneeded ones
64 are not changed.
65
66
67 The ranged form (<expr1> .. <expr2>):
68
69 <expr1> and <expr2> are evaluated and must yield integers.
70 The loop will count up <var> from <expr1> to <expr2>, basically
71 implementing a counted loop.
72
73 If <expr1> is less than <expr2>, the loop will terminate at once.
74
75 If there are more than variable, the unneeded ones are not
76 changed.
77
78
79
80 WHAT HAPPENS IF <expr> IS CHANGED IN THE LOOP?
81
82 If <expr> yields an array or struct:
83 - assignments to single elements or to array ranges effect
84 the values assigned to the variable:
85 a = ({1, 2, 3})
86 foreach(x : a) { a[1..2] = ({4, 5}); write(x+" "); }
87 will write ("1 4 5 ").
Zesstra7ea4a032019-11-26 20:11:40 +010088 - operations which implicitly copy the array or struct (this
MG Mud User88f12472016-06-24 23:31:02 +020089 includes range assignments which change the size) don't
90 have an effect on the loop.
91
92 If <expr> yields a mapping, the loop will run over the indices
93 the mapping had at the begin of the loop. Deleted indices are silently
94 skipped, new indices ignored, but changes of the data of existing
95 indices are acknowledged.
96
97 If <expr> yields a string, the value used at the start of the loop
98 remains.
99
100
101WARNING
102 The additional syntax forms using "in" as keyword are meant
103 to make re-engineering of MudOS objects easier. Do not use them
104 for newly written code, as they may not be available in future.
105
106
107EXAMPLES
108 // Call quit() in all interactive users
109 foreach(o : users()) o->quit();
110 foreach(object o : users()) o->quit();
111
112 // Print the contents of a mapping <m>
113 foreach(key, value : m) printf("%O:%O\n", key, value);
114 foreach(mixed key, mixed value : m) printf("%O:%O\n", key, value);
115
116 // Don't change the content of a string: s remains "FOOBAR".
117 s = "FOOBAR";
118 foreach(i : s) i += 32;
119
120 // Do change the content of a string: s will become "foobar".
121 s = "FOOBAR";
122 foreach(i : &s) i += 32;
123
124 // Count from 0 to 5
125 foreach(i : 6) printf("%d\n", i);
126
127 // Count from 1 to 6
128 foreach(i : 1 .. 6) printf("%d\n", i);
129
130HISTORY
131 LDMud 3.3.44 introduced the use of references, the loop over
132 an integer expression, and the loop over an integer range.
133 LDMud 3.3.266 added support for structs.
Zesstra3085c662025-08-02 18:31:10 +0200134 LPMud 3.6.5 added support for coroutines.
MG Mud User88f12472016-06-24 23:31:02 +0200135
136
137SEE ALSO
Zesstra3085c662025-08-02 18:31:10 +0200138 for(LPC), yield(LPC)