NAME foreach SYNTAX foreach ( : ) ; foreach (, , ... , : ) ; foreach ( : .. ) ; foreach (, , ... , : .. ) ; /* MudOS compatibility only - not for new code: */ foreach ( in ) ; foreach (, , ... , in ) ; DESCRIPTION The instruction evaluates its range specification - either a simple which can yield an array, a struct, a string, a mapping or an integer, or an integer range through - and executes once for each value in the range. The respective value is assigned to right before is executed. A 'break' in the will terminate the loop. A 'continue' will continue the execution from the beginning of the loop. Every specification can declare a new local variable, whose scope is the whole foreach() statement. The normal form (one ): is evaluated and has to yield an array, a struct, a string or a mapping (or reference to the former), or an integer. If is a array, struct, or string, the values of (in case of the string, the integer values of the characters) are then assigned one by one in order of occurence to , and is executed for every assignment. If is a mapping, the keys are assigned one by one to , and the values for each key are assigned in order to ... If there are more values than variable, the extraneous values are ignored. Due to the nature of mappings, a specific order of the keys can not be guaranteed. If evaluates to a reference to an array, mapping, or string, the loop will assign references to the values into the variables. This allows the loop body to change the contents of the original data. If evaluates to an integer, the loop will count up from 0 to -1, basically implementing a count loop. If evaluates to a coroutine, the loop will call the coroutine until the coroutine finishes execution. All values from the coroutine's yield() calls will be assigned to , essentially using the coroutine as a generator function. If there are more variables than necessary, the unneeded ones are not changed. The ranged form ( .. ): and are evaluated and must yield integers. The loop will count up from to , basically implementing a counted loop. If is less than , the loop will terminate at once. If there are more than variable, the unneeded ones are not changed. WHAT HAPPENS IF IS CHANGED IN THE LOOP? If yields an array or struct: - assignments to single elements or to array ranges effect the values assigned to the variable: a = ({1, 2, 3}) foreach(x : a) { a[1..2] = ({4, 5}); write(x+" "); } will write ("1 4 5 "). - operations which implicitly copy the array or struct (this includes range assignments which change the size) don't have an effect on the loop. If yields a mapping, the loop will run over the indices the mapping had at the begin of the loop. Deleted indices are silently skipped, new indices ignored, but changes of the data of existing indices are acknowledged. If yields a string, the value used at the start of the loop remains. WARNING The additional syntax forms using "in" as keyword are meant to make re-engineering of MudOS objects easier. Do not use them for newly written code, as they may not be available in future. EXAMPLES // Call quit() in all interactive users foreach(o : users()) o->quit(); foreach(object o : users()) o->quit(); // Print the contents of a mapping foreach(key, value : m) printf("%O:%O\n", key, value); foreach(mixed key, mixed value : m) printf("%O:%O\n", key, value); // Don't change the content of a string: s remains "FOOBAR". s = "FOOBAR"; foreach(i : s) i += 32; // Do change the content of a string: s will become "foobar". s = "FOOBAR"; foreach(i : &s) i += 32; // Count from 0 to 5 foreach(i : 6) printf("%d\n", i); // Count from 1 to 6 foreach(i : 1 .. 6) printf("%d\n", i); HISTORY LDMud 3.3.44 introduced the use of references, the loop over an integer expression, and the loop over an integer range. LDMud 3.3.266 added support for structs. LPMud 3.6.5 added support for coroutines. SEE ALSO for(LPC), yield(LPC)