In Control flow§
See primary documentation in context for do
The simplest way to run a block where it cannot be a stand-alone statement is by writing do
before it:
# This dies half of the time do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win.";
Note that you need a space between the do
and the block.
The whole do {...}
evaluates to the final value of the block. The block will be run when that value is needed in order to evaluate the rest of the expression. So:
False and do { 42.say };
...will not say 42. However, the block is only evaluated once each time the expression it is contained in is evaluated:
# This says "(..1 ..2 ..3)" not "(..1 ...2 ....3)" my $f = "."; say do { $f ~= "." } X~ 1, 2, 3;
In other words, it follows the same reification rules as everything else.
Technically, do
is a loop which runs exactly one iteration.
A do
may also be used on a bare statement (without curly braces) but this is mainly just useful for avoiding the syntactical need to parenthesize a statement if it is the last thing in an expression:
3, do if 1 { 2 } ; # OUTPUT: «(3, 2)» 3, (if 1 { 2 }) ; # OUTPUT: «(3, 2)»
3, if 1 { 2 } ; # Syntax error
As a consequence, do
does not run blocks that, by their syntax, must be functions. For example, if ->
is used to specify a signature, do
treats these as single-expression statements.
Thus, adding ->
to our first example prevents the closure from being evaluated:
# This never dies and never prints "Heads I win, tails I die." do -> { say "Heads I win, tails I die."; Bool.pick } or die; say "I win.";