https://wiki.tinymux.org/index.php?title=Iter()&feed=atom&action=historyIter() - Revision history2024-03-28T18:23:25ZRevision history for this page on the wikiMediaWiki 1.41.0https://wiki.tinymux.org/index.php?title=Iter()&diff=2911&oldid=prevJavelin: Add %i<n>2006-07-13T22:06:15Z<p>Add %i<n></p>
<p><b>New page</b></p><div>[[Category:Functions]]<br />
== Description == <br />
FUNCTION: {{function|iter}}(''list'', ''eval'' [, ''input delimiter'' [, ''output delimiter'']])<br />
<br />
The name of the function [[iter()]] appropriately comes from the word ''iterate'' as [[iter()]] iterates over an input list to form an output list. The input and output [[delimiter]]s control how the input ''list'' is broken down into items which are then fed into ''eval'' resulting in other items which are then formed into the output list and returned.<br />
<br />
That is, the string, ''eval'', is evaluated once for each item in ''list'' replacing the special symbol, [[PoundPound|##]], with the corresponding item from the input list and the symbol [[PoundAt|#@]] with the position within the list being iterated (starting with 1).<br />
<br />
The result of [[iter()]] is an output list. The effect is very similar to [[@dolist]] except that the results are made into a list and returned instead of executed.<br />
<br />
All [[servers]] support single-character [[delimiter]]s and the use of [[PercentR|%r]] as an output [[delimiter]]. All [[servers]] support some notation for indicating that output items should not be delimited from each other. See below for details.<br />
<br />
By default, input and output [[delimiter]]s are both spaces.<br />
<br />
Related Topics: [[@dolist]], [[ilev()]], [[inum()]], [[itext()]], [[list()]], [[parse()]].<br />
<br />
== Examples ==<br />
<br />
: <tt>> say iter(This is a test,strlen(##))<br />
: You say "4 2 1 4"<br />
: > say iter(lnum(10),mul(mul(##,##),10))<br />
: You say "0 10 40 90 160 250 360 490 640 810"<br />
: > say iter(lcon(me),[name(##)]..[money(##)])<br />
: You say "test..1 t1..1 radio..1 The Wizard's Pointy Hat..1"<br />
: > say iter(Was it a cat I saw,[words(##)] #@,s)<br />
: You say "1 1 4 2 1 3"</tt><br />
<br />
iter() adds a space between items by default. The way around this is to make use of the null output delimiter, thus:<br />
<br />
: <tt>> say iter(This is a test,strlen(##),,@@)<br />
: You say "4214"</tt><br />
<br />
== Server Differences ==<br />
<br />
=== [[AtAt|@@]] ===<br />
<br />
The default output delimiter across MUSH platforms is a single space, but there are times when it is desireable to have no output delimiter at all. On [[PennMUSH]] and [[RhostMUSH]], this is accomplished by using a fourth, empty argument. That is, 'iter(1 2 3,##,,)' evaluates to '123' on [[PennMUSH]] and [[RhostMUSH]].<br />
<br />
On [[TinyMUSH]] and [[TinyMUX]], even with a fourth, empty argument, the default output delimiter continues to be a single space. To achieve no output delimiter at all, the so-called NULL delimiter, [[AtAt|@@]], notation is used. That is, 'iter(1 2 3,##,,@@)' evalutes to '123' on [[TinyMUSH]] and [[TinyMUX]].<br />
<br />
=== [[PoundPound|##]] and [[PoundAt|#@]] ===<br />
<br />
On [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]], ''eval'' is evaluated after [[PoundPound|##]] and [[PoundAt|#@]] are substituted. This behavior opens a softcode security hole if the input list contains unvalidated data from a different security context. For this reason, [[itext()]] is preferred over [[PoundPound|##]], and [[inum()]] is preferred over [[PoundAt|#@]] whenever the input list contains unvalidated data from a different security context. It is still perfectly reasonable to use [[PoundPound|##]] and [[PoundAt|#@]] when the input list contains only data originating from the same security context as the [[iter()]] call itself.<br />
<br />
A second issue with the above behavior is that [[iter()]] cannot be nested in a useful way. The substitution is made once by the outer-most [[iter()]]. That is, the result of 'iter(1 2 3,iter(A B C,##))' is '1 1 1 2 2 2 3 3 3' on [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]].<br />
<br />
On [[TinyMUSH]], [[PoundPound|##]] and [[PoundAt|#@]] are treated as tokens by the parser. That is, the result of 'iter(1 2 3,iter(A B C,##))' is 'A B C A B C A B C'. As a token, the value is controlled by the inner-most [[iter()]]. In this approach, there is no second evaluation of items in the input list, and therefore, there is no security vunerability from parsing unvalidated data from a different security context.<br />
<br />
Notice that in both cases, [[PoundPound|##]] can only refer to the value of items at exactly one level of nesting.<br />
<br />
Even using [[itext()]], [[inum()]], and [[ilev()]] has problems. PennMUSH, RhostMUSH, and TinyMUX support nested [[iter()]] calls and transform 'iter(1 2 3,iter(A B C,itext(0)[itext(1)]))' into 'A1 B1 C1 A2 B2 C2 A3 B3 C3', but TinyMUSH transforms 'iter(1 2 3,iter(A B C,itext(0)[itext(1)]))' into '1A 1B 1C 2A 2B 2C 3A 3B 3C'. That is, TinyMUSH treats the nesting level opposite from PennMUSH, RhostMUSH, and TinyMUX.<br />
<br />
The [[itext()]], [[inum()]], and [[ilev()]] functions support full access to items at all nesting levels from any nesting level and are safe to use with unvalidated data from a different security context. In [[PennMUSH]], [[itext()]] with levels 0-9 can be abbreviated as %i<level>, e.g. %i0 is itext(0).<br />
<br />
Here are some edge cases that explore some of the quirky behaviors:<br />
<br />
'iter(1 2 ##,iter(A B C,##))' evaluate to '1 1 1 2 2 2 A B C' on [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]], and 'A B C A B C A B C' on [[TinyMUSH]].<br />
<br />
Next consider,<br />
<br />
: &foo me=##-##-##<br />
: think iter(1 2 3,u(foo))<br />
<br />
On [[TinyMUSH]], this gives '1-1-1 2-2-2 3-3-3', but on [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]], this gives '##-##-## ##-##-## ##-##-##'.<br />
<br />
That is, [[TinyMUSH]] substitutes deeply in a potentially undesireable and unexpected way, but [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]] treat the input list in a potentially undesireable and unexpected way.<br />
<br />
For all of these reasons, and also because at some point [[PennMUSH]], [[RhostMUSH]], and [[TinyMUX]] could potentially change to the [[TinyMUSH]] behavior, the use of [[itext()]], [[inum()]], and [[ilev()]] is recommend in cases where a specific behavior is required.<br />
<br />
=== Multi-Character Delimiters ===<br />
<br />
[[TinyMUSH]] 3.1 and [[TinyMUX]] 2.4 support multi-character input and output delimiters. That is, 'iter(1--2--3,##,--,==)' produces '1==2==3'.<br />
[[PennMUSH]] and [[RhostMUSH]] support single-character input delimiters, but multi-character output delimiters. That is, 'iter(1-2-3,##,-,==)' produces '1==2==3'.<br />
<br />
<br />
For servers that support multi-characters delimiters, you can use [[PercentR|%r]] as part of an input delimiter.<br />
<br />
=== Compatibility Attempts ===<br />
<br />
On [[PennMUSH]] and [[TinyMUX]], [[parse()]] is a built-in alias for [[iter()]]. On [[TinyMUSH]], [[parse()]] behaves like [[PennMUSH]]'s and [[TinyMUX]]'s [[iter()]] by treating [[PoundPound|##]] and [[PoundAt|#@]] as substitutions instead of tokens.</div>Javelin