class Capture { }

A Capture is a container for passing arguments to a code object. Captures are the flip-side of Signatures. Thus, captures are the caller-defined arguments, while signatures are the callee-defined parameters. For example when you call print $a, $b, the $a, $b part is a capture.

Captures contain a list-like part for positional arguments and a hash-like part for named arguments, thus behaving as Positional and Associative, although it does not actually mix in those roles. Like any other data structure, a stand-alone capture can be created, stored, and used later.

A literal Capture can be created by prefixing a term with a backslash \. Commonly, this term will be a List of terms, from which the forms key => value and :key<value> of a Pair literal will be placed in the named part, and all other terms will be placed in the positional part (including Pairs of the form 'key' => value).

my $a = \(42);                      # Capture with one positional arg 
my $b = \(12verbose => True);   # Capture with two positional args and one named arg 
my $c = \(12:verbose(True));    # same as before 
my $c = \(12'verbose' => True); # Capture with three positional args

To reiterate, named arguments in a capture must be created using one of two ways:

  • Use an unquoted key naming a parameter, followed by =>, followed by the argument. For example, as => by => {1/$_}.

  • Use a colon-pair literal named after the parameter. For example, :into(my %leap-years).

For example:

sub greet(:$name:$age{
    "$name$age"
}
 
my $d = \(name => 'Mugen'age => 19);   # OK 
my $e = \(:name('Jin'), :age(20));       # OK 
my $f = \('name' => 'Fuu''age' => 15); # Not OK, keys are quoted.

For the greet subroutine that accepts two named arguments name and age, the captures $d and $e will work fine while the capture $f will throw a Too many positionals passed... error. This is because 'age' => 20 isn't a named argument (as per the two ways of creating one mentioned above) but a positional argument of which greet expects none. In the context of captures, quoted keys don't create named arguments. Any 'key' => value is just another positional parameter, thus exercise some caution when creating captures with named arguments.

Once a capture is created, you may use it by prefixing it with a vertical bar | in a subroutine call, and it will be as if the values in the capture were passed directly to the subroutine as arguments — named arguments will be passed as named arguments and positional arguments will be passed as positional arguments. You may re-use the capture as many times as you want, even with different subroutines.

say greet |$d;                # OUTPUT: «Mugen, 19␤» 
say greet |$e;                # OUTPUT: «Jin, 20␤» 
my $x = \(423-2);
say reverse |$x;              # OUTPUT: «(-2 3 2 4)␤» 
say sort 5|$x;              # OUTPUT: «(-2 2 3 4 5)␤» 
 
say unique |$xas => {.abs}# OUTPUT: «(4 2 3)␤» 
say unique |$x:as({.abs});  # OUTPUT: «(4 2 3)␤» 
 
my $y = \(173by => {1/$_});
say min |$y;                  # OUTPUT: «7␤», same as min 1, 7, 3, by => {1/$_} 
say max |$y;                  # OUTPUT: «1␤», same as max 1, 7, 3, by => {1/$_}

Inside a Signature, a Capture may be created by prefixing a sigilless parameter with a vertical bar |. This packs the remainder of the argument list into that capture parameter.

sub f($a|c{
    say $a;
    say c;
    say c.^name;
    say c.list# see Methods section 
    say c.hash# see Methods section 
}
 
f 123=> 4:b(5);
# OUTPUT: 
# 1 
# \(2, 3, :a(4), :b(5)) 
# Capture 
# (2 3) 
# Map.new((a => 4, b => 5))

Note that Captures are still Lists in that they may contain containers, not just literal values:

my $b = 1;
my $c = \(42$b3);
say min |$c;        # OUTPUT: «1␤» 
$b = -5;
say min |$c;        # OUTPUT: «-5␤»

Methods§

method list§

method list(Capture:D:)

Returns the positional part of the Capture.

my Capture $c = \(235apples => (red => 2));
say $c.list# OUTPUT: «(2 3 5)␤»

method hash§

method hash(Capture:D:)

Returns the named/hash part of the Capture.

my Capture $c = \(235apples => (red => 2));
say $c.hash# OUTPUT: «Map.new((:apples(:red(2))))␤»

method elems§

method elems(Capture:D: --> Int:D)

Returns the number of positional elements in the Capture.

my Capture $c = \(235apples => (red => 2));
say $c.elems# OUTPUT: «3␤»

method keys§

multi method keys(Capture:D: --> Seq:D)

Returns a Seq containing all positional keys followed by all named keys. For positional arguments the keys are the respective arguments ordinal position starting from zero.

my $capture = \(235apples => (red => 2));
say $capture.keys# OUTPUT: «(0 1 2 apples)␤»

method values§

multi method values(Capture:D: --> Seq:D)

Returns a Seq containing all positional values followed by all named argument values.

my $capture = \(235apples => (red => 2));
say $capture.values# OUTPUT: «(2 3 5 red => 2)␤»

method kv§

multi method kv(Capture:D: --> Seq:D)

Returns a Seq of alternating keys and values. The positional keys and values, if any, comes first followed by the named keys and values.

my $capture = \(23apples => (red => 2));
say $capture.kv# OUTPUT: «(0 2 1 3 apples red => 2)␤»

method pairs§

multi method pairs(Capture:D: --> Seq:D)

Returns all arguments, the positional followed by the named, as a Seq of Pairs. Positional arguments have their respective ordinal value, starting at zero, as key while the named arguments have their names as key.

my Capture $c = \(23apples => (red => 2));
say $c.pairs# OUTPUT: «(0 => 2 1 => 3 apples => red => 2)␤»

method antipairs§

multi method antipairs(Capture:D: --> Seq:D)

Returns all arguments, the positional followed by the named, as a Seq of Pairs where the keys and values have been swapped, i.e. the value becomes the key and the key becomes the value. This behavior is the opposite of the <pairs|#method_pairs> method.

my $capture = \(23apples => (red => 2));
say $capture.antipairs# OUTPUT: «(2 => 0 3 => 1 (red => 2) => apples)␤»

method Bool§

method Bool(Capture:D: --> Bool:D)

Returns True if the Capture contains at least one named or one positional argument.

say \(1,2,3apples => 2).Bool# OUTPUT: «True␤» 
say \().Bool;                   # OUTPUT: «False␤»

method Capture§

method Capture(Capture:D: --> Capture:D)

Returns itself, i.e. the invocant.

say \(1,2,3apples => 2).Capture# OUTPUT: «\(1, 2, 3, :apples(2))␤»

method Numeric§

method Numeric(Capture:D: --> Int:D)

Returns the number of positional elements in the Capture.

say \(1,2,3apples => 2).Numeric# OUTPUT: «3␤»

Typegraph§

Type relations for Capture
raku-type-graph Capture Capture Any Any Capture->Any Mu Mu Any->Mu Cool Cool Cool->Any Match Match Match->Capture Match->Cool Grammar Grammar Grammar->Match

Expand chart above