Documentation for control flow gather take

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

language documentation Control Flow

From Control Flow

(Control Flow) control flow gather take

gather is a statement or block prefix that returns a sequence of values. The values come from calls to take in the dynamic scope of the gather block.

my @a = gather {
    take 1;
    take 5;
    take 42;
}
say join ''@a;          # OUTPUT: «1, 5, 42␤» 

gather/take can generate values lazily, depending on context. If you want to force lazy evaluation use the lazy subroutine or method. Binding to a scalar or sigilless container will also force laziness.

For example

my @vals = lazy gather {
    take 1;
    say "Produced a value";
    take 2;
}
say @vals[0];
say 'between consumption of two values';
say @vals[1];
 
# OUTPUT: 
# 1 
# between consumption of two values 
# Produced a value 
# 2 

gather/take is scoped dynamically, so you can call take from subs or methods that are called from within gather:

sub weird(@elems:$direction = 'forward'{
    my %direction = (
        forward  => sub { take $_ for @elems },
        backward => sub { take $_ for @elems.reverse },
        random   => sub { take $_ for @elems.pick(*},
    );
    return gather %direction{$direction}();
}
 
say weird(<a b c>:direction<backward> );          # OUTPUT: «(c b a)␤» 

If values need to be mutable on the caller side, use take-rw.