syntax gather take

Documentation for syntax gather take assembled from the following types:

language documentation Control flow

From Control flow

(Control flow) control flow gather take 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.

Note that gather/take also work for hashes. The return value is still a Seq but the assignment to a hash in the following example makes it a hash.

my %h = gather { take "foo" => 1take "bar" => 2};
say %h;                                             # OUTPUT: «{bar => 2, foo => 1}␤»