Rules / Types, classes & roles / composite

Pair Reference

Key/value pair

What it is #

Routines #

Signatures are reproduced from the documentation, including their declared return types. A routine listed here is part of the type's published interface; whether Raku++ implements it is a separate question, answered by the examples below.

method new #

multi method new(Pair: Mu  $key, Mu  $value)
multi method new(Pair: Mu :$key, Mu :$value)

Constructs a new Pair object.

method ACCEPTS #

multi method ACCEPTS(Pair:D $: %topic)
multi method ACCEPTS(Pair:D $: Pair:D $topic)
multi method ACCEPTS(Pair:D $: Mu $topic)

If %topic is an Associative, looks up the value using invocant's key in it and checks invocant's value .ACCEPTS that value: If $topic is another Pair, checks the invocant's key and value .ACCEPTS the $topic's key and value respectively: If $topic is any other value, the invocant Pair's key is treated as a method name. This method is called on $topic, the Bool result of which is compared

method antipair #

method antipair(Pair:D: --> Pair:D)

Returns Pair:D.

Returns a new Pair object with key and value exchanged.

method key #

multi method key(Pair:D:)

Returns the key part of the Pair.

method value #

multi method value(Pair:D:) is rw

Returns the value part of the Pair.

infix cmp #

multi infix:<cmp>(Pair:D, Pair:D)

The type-agnostic comparator; compares two Pairs. Compares first their key parts, and then compares the value parts if the keys are equal.

method fmt #

multi method fmt(Pair:D: Str:D $format --> Str:D)

Returns Str:D.

Takes a format string, and returns a string the key and value parts of the Pair formatted. Here's an example: For more about format strings, see sprintf.

method kv #

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

Returns Seq:D.

Returns a two-element Seq with the key and value parts of Pair, in that order. This method is a special case of the same-named method on Hash, which returns all its entries as a list of keys and values.

method pairs #

multi method pairs(Pair:D:)

Returns a list of one Pair, namely this one.

method antipairs #

multi method antipairs(Pair:D:)

Returns a List containing the antipair of the invocant.

method invert #

method invert(Pair:D: --> Seq:D)

Returns Seq:D.

Returns a Seq. If the .value of the invocant is NOT an Iterable, the Seq will contain a single Pair whose .key is the .value of the invocant and whose .value is the .key of the invocant: If invocant's .value is an Iterable, the returned Seq will contain the same number of Pairs as items in the .value, with each

method keys #

multi method keys(Pair:D: --> List:D)

Returns List:D.

Returns a List containing the key of the invocant.

method values #

multi method values(Pair:D: --> List:D)

Returns List:D.

Returns a List containing the value of the invocant.

method freeze #

method freeze(Pair:D:)

Makes the value of the Pair read-only, by removing it from its Scalar container, and returns it. NOTE: this method is deprecated as of 6.d language version. Instead, create a new Pair, with a decontainerized key/value.

method Str #

multi method Str(Pair:D: --> Str:D)

Returns Str:D.

Returns a string representation of the invocant formatted as key ~ \t ~ value.

method Pair #

method Pair()

Returns the invocant Pair object.

Examples, run three ways #

Every example below comes from the official documentation, together with the output that documentation asserts. Each was then executed by Rakudo and by Raku++ when this page was built. Where the three agree, one result is shown; where they do not, all three are — because which of them is wrong is exactly the information worth having.

2 all-differ · 3 doc-drift · 5 no-output · 2 not-runnable · 19 ok · 1 rakudo-differs · 3 rakupp-differs

class Pair does Associative {}

Not executed: the documentation states no expected output for this example.

Pair.new('key', 'value'); # The canonical way
'key' => 'value';         # this...
:key<value>;              # ...means the same as this
:key<value1 value2>;      # But this is  key => <value1 value2>
:foo(127);                # short for  foo => 127
:127foo;                  # the same   foo => 127

Not executed: the documentation states no expected output for this example.

# use MATHEMATICAL DOUBLE-STRUCK DIGIT THREE
say (:𝟛math-three);         # OUTPUT: «math-three => 3␤»
Output
math-three => 3

Documentation, Rakudo and Raku++ all agree.

say :7̈a

Not executed: the documentation states no expected output for this example.

(foo => 127)              # the same   foo => 127

Not executed: the documentation states no expected output for this example.

:key;                     # same as   key => True
:!key;                    # same as   key => False

Not executed: the documentation states no expected output for this example.

sub colon-pair( :$key-value ) {
say $key-value;
}
my $key-value = 'value';
colon-pair( :$key-value );               # OUTPUT: «value␤»
colon-pair( key-value => $key-value );   # OUTPUT: «value␤»
Output
value
value

Documentation, Rakudo and Raku++ all agree.

sub s(*%h){ say %h.raku };
s :a1:b2;
# OUTPUT: «{:a1, :b2}␤»
Documentation
{:a1, :b2}
Rakudo
{:a1, :b2}
Raku++

Raku++ disagrees with both the documentation and Rakudo — a defect.

my $manna = :a1:b2:c3;
say $manna.^name;
# OUTPUT: «Pair␤»
Output
Pair

Documentation, Rakudo and Raku++ all agree.

$manna = (:a1:b2:c3);
say $manna.^name;
# OUTPUT: «List␤»

Neither engine can run this in isolation — the example depends on context from the surrounding text.

my $bar = 10;
my $p   = :$bar;
say $p; # OUTPUT: «bar => 10␤»
Output
bar => 10

Documentation, Rakudo and Raku++ all agree.

my $v = 'value A';
my $pair = a => $v;
$pair.say;  # OUTPUT: «a => value A␤»

$v = 'value B';
$pair.say;  # OUTPUT: «a => value B␤»
Documentation
a => value A
a => value B
Rakudo
a => value A
a => value B
Raku++
a => value A
a => value A

Raku++ disagrees with both the documentation and Rakudo — a defect.

my $v = 'value B';
my $pair = a => $v;
$pair.freeze;
$v = 'value C';
$pair.say; # OUTPUT: «a => value B␤»
Output
a => value B

Documentation, Rakudo and Raku++ all agree.

my $pair = a => 5;
say $pair<a>;           # OUTPUT: «5␤»
say $pair<a>:exists;    # OUTPUT: «True␤»
say $pair<no-such-key>; # OUTPUT: «Nil␤»
Output
5
True
Nil

Documentation, Rakudo and Raku++ all agree.

say %(:42a) ~~ :42a; # OUTPUT: «True␤»
say %(:42a) ~~ :10a; # OUTPUT: «False␤»
Output
True
False

Documentation, Rakudo and Raku++ all agree.

say :42a ~~ :42a; # OUTPUT: «True␤»
say :42z ~~ :42a; # OUTPUT: «False␤»
say :10a ~~ :42a; # OUTPUT: «False␤»
Output
True
False
False

Documentation, Rakudo and Raku++ all agree.

say 3 ~~ :is-prime;             # OUTPUT: «True␤»
say 3 ~~  is-prime => 'truthy'; # OUTPUT: «True␤»
say 4 ~~ :is-prime;             # OUTPUT: «False␤»
Documentation
True
True
False
Rakudo
True
True
False
Raku++
True
False => truthy
False

Raku++ disagrees with both the documentation and Rakudo — a defect.

say "foo" .IO ~~ :f & :rw; # OUTPUT: «False␤»
say "/tmp".IO ~~ :!f;      # OUTPUT: «True␤»
say "."   .IO ~~ :f | :d;  # OUTPUT: «True␤»
Documentation
False
True
True
Rakudo
True
True
True
Raku++
True
True
True

Both engines agree; the documentation states something else. Trust the engines.

my $p = (d => 'Raku').antipair;
say $p.key;         # OUTPUT: «Raku␤»
say $p.value;       # OUTPUT: «d␤»
Output
Raku
d

Documentation, Rakudo and Raku++ all agree.

my $p = (Raku => "d");
say $p.key; # OUTPUT: «Raku␤»
Output
Raku

Documentation, Rakudo and Raku++ all agree.

my $p = (Raku => "d");
say $p.value; # OUTPUT: «d␤»
Output
d

Documentation, Rakudo and Raku++ all agree.

my $a = (Apple => 1);
my $b = (Apple => 2);
say $a cmp $b; # OUTPUT: «Less␤»
Output
Less

Documentation, Rakudo and Raku++ all agree.

my $pair = :Earth(1);
say $pair.fmt("%s is %.3f AU away from the sun")
# OUTPUT: «Earth is 1.000 AU away from the sun␤»
Output
Earth is 1.000 AU away from the sun

Documentation, Rakudo and Raku++ all agree.

my $p = (Raku => "d");
say $p.kv[0]; # OUTPUT: «Raku␤»
say $p.kv[1]; # OUTPUT: «d␤»
Output
Raku
d

Documentation, Rakudo and Raku++ all agree.

my $p = (Raku => "d");
say $p.pairs.^name; # OUTPUT: «List␤»
say $p.pairs[0];    # OUTPUT: «Raku => d␤»
Documentation
List
Raku => d
Rakudo
Seq
Raku => d
Raku++
Seq
Raku => d

Both engines agree; the documentation states something else. Trust the engines.

my $p = (d => 'Raku').antipairs;
say $p.^name;                                     # OUTPUT: «List␤»
say $p.first;                                     # OUTPUT: «Raku => d␤»
say $p.first.^name;                               # OUTPUT: «Pair␤»
Documentation
List
Raku => d
Pair
Rakudo
Seq
Raku => d
Raku++
Seq
Raku => d
Pair

All three differ. Needs a human.

Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.

:foo<bar>.invert.raku.say; # OUTPUT: «(:bar("foo"),).Seq␤»
Output
(:bar("foo"),).Seq

Documentation, Rakudo and Raku++ all agree.

:foo<Raku is great>.invert.raku.say;
# OUTPUT: «(:Raku("foo"), :is("foo"), :great("foo")).Seq␤»
Output
(:Raku("foo"), :is("foo"), :great("foo")).Seq

Documentation, Rakudo and Raku++ all agree.

:foo{ :42a, :72b }.invert.raku.say;
# OUTPUT: «((:a(42)) => "foo", (:b(72)) => "foo").Seq␤»
Documentation
((:a(42)) => "foo", (:b(72)) => "foo").Seq
Rakudo
((:b(72)) => "foo", (:a(42)) => "foo").Seq
Raku++
((:a(42)) => "foo", (:b(72)) => "foo").Seq

Raku++ matches the documentation; Rakudo does not. This is the one class where neither engine can be assumed right: it may be a stale doc that Raku++ was built from, or it may be a Rakudo bug that the documentation predates. Each case is examined individually.

Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.

say (Raku => "d").keys;                           # OUTPUT: «(Raku)␤»
Output
(Raku)

Documentation, Rakudo and Raku++ all agree.

say (Raku => "d").values;                         # OUTPUT: «(d)␤»
Output
(d)

Documentation, Rakudo and Raku++ all agree.

my $str = "apple";
my $p = Pair.new('key', $str);
$p.value = "orange";              # this works as expected
$p.say;                           # OUTPUT: «key => orange␤»
$p.freeze.say;                    # OUTPUT: «orange␤»
$p.value = "a new apple";         # Fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Str (apple)␤»
Documentation
key => orange
orange
X::Assignment::RO: Cannot modify an immutable Str (apple)
Rakudo
key => orange
orange
X::Assignment::RO: Cannot modify an immutable Str (orange)
Raku++
key => orange
key => orange

All three differ. Needs a human.

Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.

$p.=Map.=head.say;                                    # OUTPUT: «orange␤»

Neither engine can run this in isolation — the example depends on context from the surrounding text.

my $b = eggs => 3;
say $b.Str;                                       # OUTPUT: «eggs  3␤»
Documentation
eggs  3
Rakudo
eggs	3
Raku++
eggs	3

Both engines agree; the documentation states something else. Trust the engines.

my $pair = eggs => 3;
say $pair.Pair === $pair;                         # OUTPUT: «True␤»
Output
True

Documentation, Rakudo and Raku++ all agree.