From TinyMUX
Jump to navigation Jump to search


COMMAND: @dolist[/<switch>] [<delimiter>] <list>=<action>

list is a list of strings, which can be object numbers, attributes, or arbitrary words. action is a command to perform once for each item in list, replacing the special symbol ## with the corresponding item from list, and the symbol #@ with the position in the list, starting with one. By default, @dolist considers each item in list to be separated with spaces. If you specify the /delimit switch, then each item is considered to be separated by delimiter. delimiter must be a single character.

If present, switch can be any of:

/space - (Default) List elements are separated by spaces.
/delimit - List elements are separated by delimiter.
/notify - Queues a '@notify' after all commands in the list.

This command is particularly handy with lcon() and lexits().

@dolist and the Queue

TinyMUX command processing is queue-based. Commands are put on the queue as they are invoked, and they execute in order-- first in, first out (with exceptions for commands entered by players, which always take precedence). This is important to remember, as @dolist, by its nature, is used to invoke one or more additional commands. As mentioned in the discussion of the queue, consider the following:

&trig.saynames me=@dolist lcon(here)=@pemit me=[space(3)][name(##)]
&cmd.saynames me=$+saynames:@tr me/trig.saynames;@pemit me=Items In Room:

While you might expect that you would see the list of names followed by the @pemit, in reality you see the "Items In Room:" header first, followed by the contents of the @dolist. This is because commands are queued as they are executed. In this case when you type +saynames, the @trigger runs and the @dolist is queued as 1, and then the @pemit is queued as 2. The @dolist is executed, and its @pemits are put at the bottom of the queue. The queue moves to the next position and the header is printed. Finally, the queue reaches the @pemits queued by the @dolist, which are then printed accordingly.

As a consequence of this, if you intend to use semaphores in conjunction with @dolist, it is necessary to use the /notify switch. This is because using a @dolist followed by a @notify will result in the @notify executing first, since the contents of the @dolist will end up being queued AFTER the @notify. Using @dolist/notify will automatically queue the notification to happen after the execution of the @dolist has finished.

&list.recitation me=I like|chickens, but|I do not like|cows.
&cmd.recite me=$+recite:@wait me=say Done!;@dolist/delimit/notify | [v(list.recitation)]="##

>You say, "I like"
>You say, "chickens, but"
>You say, "I do not like"
>You say, "cows."
>You say, "Done!"

This works as expected, because each line is queued right away, and an @notify is queued after them.

&trig.command1 me=say I like
&trig.command2 me=say chickens, but
&trig.command3 me=say I do not like
&trig.command4 me=say cows.
&cmd.recite me=$+recite:@wait me=say Done!;@dolist/notify [secure(lattr(me/trig.command?))]=@tr/quiet me/##

> You say, "Done!"
> You say, "I like"
> You say, "chickens, but"
> You say, "I do not like"
> You say, "cows."

This does not work as some might expect. The @dolist queues up all of its @triggers followed by an @notify. As the queue executes, each @trigger puts its command at the end of the queue, then the @notify executes, and then the individual say commands execute.


@dolist [lcon(here)] = "[name(##)](##)
@dolist [lcon(here)] = @switch [get(##/last)]=*1990*,"[name(##)]
@va me = va vb vc
@do list [get(me/va)] = @emit [get(me/##)]
@dolist Frodo Bilbo Gandalf = page ## = HELP!!!! I've fallen into a pit.
@dolist/delimit , {Frodo, Bilbo Baggins, Gandalf} = page ## = HELP!!!!
@wait me="This is a semaphore.
@dolist/notify lnum(3)=say ##
> You say, "0"
> You say, "1"
> You say, "2"
> You say, "This is a semaphore."

Related Topics

iter(), parse(), @notify, Semaphores, Queue.