control flow for

Documentation for control flow for, assembled from the following types:

language documentation Control Flow

From Control Flow

(Control Flow) control flow for

The for loop iterates over a list, running the statements inside a block once on each iteration. If the block takes parameters, the elements of the list are provided as arguments.

my @foo = 1..3;
for @foo { $_.print } # prints each value contained in @foo 
for @foo { .print }   # same thing, because .print implies a $_ argument 
for @foo { 42.print } # prints 42 as many times as @foo has elements 

Pointy block syntax or a placeholder may be used to name the parameter, of course.

my @foo = 1..3;
for @foo -> $item { print $item }
for @foo { print $^item }            # same thing 

Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.

my @foo = 1..3;
for @foo.kv -> $idx$val { say "$idx$val" }
my %hash = <a b c> Z=> 1,2,3;
for %hash.kv -> $key$val { say "$key => $val" }
for 11.122.1 { say "$^x < $^y" }  # says "1 < 1.1" then says "2 < 2.1" 

Parameters of a pointy block can have default values, allowing to handle lists with missing elements.

my @list = 1,2,3,4;
for @list -> $a$b = 'N/A'$c = 'N/A' {
    say "$a $b $c"
}
# OUTPUT: «1 2 3␤4 N/A N/A␤» 

If the postfix form of for is used a block is not required and the topic is set for the statement list.

say $_ butterflies! for <♥ ♥ ♥>;
# OUTPUT«I ♥ butterflies!␤I ♥ butterflies!␤I ♥ butterflies!␤» 

A for may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:

for $*IN.lines -> $line { .say }

Iteration variables are always lexical, so you don't need to use my to give them the appropriate scope. Also, they are read-only aliases. If you need them to be read-write, use <-> instead of ->. If you need to make $_ read-write in a for loop, do so explicitly.

my @foo = 1..3;
for @foo <-> $_ { $_++ }

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:

(for 123 { $_ * 2 }).say;              # says "(2 4 6)" 
my @a = do for 123 { $_ * 2 }@a.say# says "[2 4 6]" 
my @b = (for 123 { $_ * 2 }); @a.say;  # same thing