class Capture

Argument list suitable for passing to a Signature

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 = \(1, 2, verbose => True);   # Capture with two positional args and one named arg
    my $c = \(1, 2, :verbose(True));    # same as before
    my $c = \(1, 2, '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 = \(4, 2, 3, -2);
    say reverse |$x;              # OUTPUT: «(-2 3 2 4)␤»
    say sort 5, |$x;              # OUTPUT: «(-2 2 3 4 5)␤»
say unique |$x, as => {.abs}; # OUTPUT: «(4 2 3)␤»
    say unique |$x, :as({.abs});  # OUTPUT: «(4 2 3)␤»
my $y = \(1, 7, 3, by => {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 1, 2, 3, a => 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 = \(4, 2, $b, 3);
    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 = \(2, 3, 5, apples => (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 = \(2, 3, 5, apples => (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 = \(2, 3, 5, apples => (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 = \(2, 3, 5, apples => (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 = \(2, 3, 5, apples => (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 = \(2, 3, apples => (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 = \(2, 3, apples => (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.

my $capture = \(2, 3, apples => (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,3, apples => 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,3, apples => 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,3, apples => 2).Numeric; # OUTPUT: «3␤»

See Also

class Array

Sequence of itemized values

class Bag

Immutable collection of distinct objects with integer weights

class BagHash

Mutable collection of distinct objects with integer weights

class Hash

Mapping from strings to itemized values

class IterationBuffer

Low level storage of positional values

class List

Sequence of values

class Map

Immutable mapping from strings to values

class Mix

Immutable collection of distinct objects with Real weights

class MixHash

Mutable collection of distinct objects with Real weights

class NFC

Codepoint string in Normal Form C (composed)

class NFD

Codepoint string in Normal Form D (decomposed)

class NFKC

Codepoint string in Normal Form KC (compatibility composed)

class NFKD

Codepoint string in Normal Form KD (compatibility decomposed)

class Pair

Key/value pair

class PseudoStash

Stash type for pseudo-packages

class Range

Interval of ordered values

class Seq

An iterable, potentially lazy sequence of values

class Set

Immutable collection of distinct objects

class SetHash

Mutable collection of distinct objects

class Slip

A kind of List that automatically flattens into an outer container

class Stash

Table for "our"-scoped symbols

class Uni

A string of Unicode codepoints

class utf8

Mutable uint8 buffer for utf8 binary data

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.