A Capture
is a container for passing arguments to a code object. Captures are the flip-side of Signature
s. 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 Pair
s of the form 'key' => value
).
my = \(42); # Capture with one positional argmy = \(1, 2, verbose => True); # Capture with two positional args and one named argmy = \(1, 2, :verbose(True)); # same as beforemy = \(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(:, :)my = \(name => 'Mugen', age => 19); # OKmy = \(:name('Jin'), :age(20)); # OKmy = \('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 |; # OUTPUT: «Mugen, 19»say greet |; # OUTPUT: «Jin, 20»
my = \(4, 2, 3, -2);say reverse |; # OUTPUT: «(-2 3 2 4)»say sort 5, |; # OUTPUT: «(-2 2 3 4 5)»say unique |, as => ; # OUTPUT: «(4 2 3)»say unique |, :as(); # OUTPUT: «(4 2 3)»my = \(1, 7, 3, by => );say min |; # OUTPUT: «7», same as min 1, 7, 3, by => {1/$_}say max |; # 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(, |c)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 Capture
s are still List
s in that they may contain containers, not just literal values:
my = 1;my = \(4, 2, , 3);say min |; # OUTPUT: «1»= -5;say min |; # OUTPUT: «-5»
Methods§
method list§
method list(Capture:)
Returns the positional part of the Capture
.
my Capture = \(2, 3, 5, apples => (red => 2));say .list; # OUTPUT: «(2 3 5)»
method hash§
method hash(Capture:)
Returns the named/hash part of the Capture
.
my Capture = \(2, 3, 5, apples => (red => 2));say .hash; # OUTPUT: «Map.new((:apples(:red(2))))»
method elems§
method elems(Capture: --> Int)
Returns the number of positional elements in the Capture
.
my Capture = \(2, 3, 5, apples => (red => 2));say .elems; # OUTPUT: «3»
method keys§
multi method keys(Capture: --> Seq)
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 = \(2, 3, 5, apples => (red => 2));say .keys; # OUTPUT: «(0 1 2 apples)»
method values§
multi method values(Capture: --> Seq)
Returns a Seq
containing all positional values followed by all named argument values.
my = \(2, 3, 5, apples => (red => 2));say .values; # OUTPUT: «(2 3 5 red => 2)»
method kv§
multi method kv(Capture: --> Seq)
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 = \(2, 3, apples => (red => 2));say .kv; # OUTPUT: «(0 2 1 3 apples red => 2)»
method pairs§
multi method pairs(Capture: --> Seq)
Returns all arguments, the positional followed by the named, as a Seq
of Pair
s. Positional arguments have their respective ordinal value, starting at zero, as key while the named arguments have their names as key.
my Capture = \(2, 3, apples => (red => 2));say .pairs; # OUTPUT: «(0 => 2 1 => 3 apples => red => 2)»
method antipairs§
multi method antipairs(Capture: --> Seq)
Returns all arguments, the positional followed by the named, as a Seq
of Pair
s 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 = \(2, 3, apples => (red => 2));say .antipairs; # OUTPUT: «(2 => 0 3 => 1 (red => 2) => apples)»
method Bool§
method Bool(Capture: --> Bool)
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: --> Capture)
Returns itself, i.e. the invocant.
say \(1,2,3, apples => 2).Capture; # OUTPUT: «\(1, 2, 3, :apples(2))»
method Numeric§
method Numeric(Capture: --> Int)
Returns the number of positional elements in the Capture
.
say \(1,2,3, apples => 2).Numeric; # OUTPUT: «3»