txt: ## pair.md
  class Pair
  
  Key/value pair
  
  ```raku
  class Pair does Associative {}
  ```
  
  Consists of two parts, a *key* and a *value*. `Pair`s can be seen as the atomic units in [`Hash`](/type/Hash)es, and they are also used in conjunction with named arguments and parameters.
  
  There are many syntaxes for creating `Pair`s:
  
  ```raku
  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
  ```
  
  Note that last form supports Non-ASCII numerics as well:
  
  ```raku
  # use MATHEMATICAL DOUBLE-STRUCK DIGIT THREE
  say (:𝟛math-three);         # OUTPUT: «math-three => 3␤»
  ```
  
  But not *synthetic* (i.e. formed by a digit and additional Unicode marks):
  
  ```raku
  say :7̈a
  
  ```
  
  You can also use an *identifier-like literal* as key; this will not need the quotes as long as it follows the syntax of [ordinary identifiers](/language/syntax#Ordinary_identifiers):
  
  ```raku
  (foo => 127)              # the same   foo => 127
  ```
  
  Variants of this are
  
  ```raku
  :key;                     # same as   key => True
  :!key;                    # same as   key => False
  ```
  
  And this other variant, to be used in routine invocation
  
  ```raku
  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␤»
  
  ```
  
  Colon pairs can be chained without a comma to create a List of Pairs. Depending on context you may have to be explicit when assigning colon lists.
  
  ```raku
  sub s(*%h){ say %h.raku };
  s :a1:b2;
  # OUTPUT: «{:a1, :b2}␤»
  
  my $manna = :a1:b2:c3;
  say $manna.^name;
  # OUTPUT: «Pair␤»
  
  $manna = (:a1:b2:c3);
  say $manna.^name;
  # OUTPUT: «List␤»
  ```
  
  Any variable can be turned into a `Pair` of its name and its value.
  
  ```raku
  my $bar = 10;
  my $p   = :$bar;
  say $p; # OUTPUT: «bar => 10␤»
  ```
  
  It is worth noting that when assigning a [`Scalar`](/type/Scalar) as value of a `Pair` the value holds the container of the value itself. This means that it is possible to change the value from outside of the `Pair` itself:
  
  ```raku
  my $v = 'value A';
  my $pair = a => $v;
  $pair.say;  # OUTPUT: «a => value A␤»
  
  $v = 'value B';
  $pair.say;  # OUTPUT: «a => value B␤»
  
  ```
  
  Please also note that this behavior is totally unrelated to the way used to build the `Pair` itself (i.e., explicit usage of `new`, use of colon, fat arrow), as well as if the `Pair` is bound to a variable.
  
  It is possible to change the above behavior forcing the `Pair` to remove the scalar container and to hold the effective value itself via the method [freeze](/type/Pair#method_freeze):
  
  ```raku
  my $v = 'value B';
  my $pair = a => $v;
  $pair.freeze;
  $v = 'value C';
  $pair.say; # OUTPUT: «a => value B␤»
  
  ```
  
  As Pair implements [`Associative`](/type/Associative) role, its value can be accessed using Associative subscription operator, however, due to Pair's singular nature, the pair's value will be only returned for the pair's key. [`Nil`](/type/Nil) object will be returned for any other key. Subscript adverbs such as `:exists` can be used on Pair.
  
  ```raku
  my $pair = a => 5;
  say $pair<a>;           # OUTPUT: «5␤»
  say $pair<a>:exists;    # OUTPUT: «True␤»
  say $pair<no-such-key>; # OUTPUT: «Nil␤»
  
  ```
  
  # [Methods](#class_Pair "go to top of document")[§](#Methods "direct link")
  
  ## [method new](#class_Pair "go to top of document")[§](#method_new "direct link")
  
  ```raku
  multi method new(Pair: Mu  $key, Mu  $value)
  multi method new(Pair: Mu :$key, Mu :$value)
  ```
  
  Constructs a new `Pair` object.
  
  ## [method ACCEPTS](#class_Pair "go to top of document")[§](#method_ACCEPTS "direct link")
  
  ```raku
  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`](/type/Associative), looks up the value using invocant's key in it and checks invocant's value `.ACCEPTS` that value:
  
  ```raku
  say %(:42a) ~~ :42a; # OUTPUT: «True␤»
  say %(:42a) ~~ :10a; # OUTPUT: «False␤»
  ```
  
  If `$topic` is another `Pair`, checks the invocant's key and value `.ACCEPTS` the `$topic`'s key and value respectively:
  
  ```raku
  say :42a ~~ :42a; # OUTPUT: «True␤»
  say :42z ~~ :42a; # OUTPUT: «False␤»
  say :10a ~~ :42a; # OUTPUT: «False␤»
  ```
  
  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`](/type/Bool) result of which is compared against the invocant `Pair`'s [`Bool`](/type/Bool) value. For example, primality can be tested using smartmatch:
  
  ```raku
  say 3 ~~ :is-prime;             # OUTPUT: «True␤»
  say 3 ~~  is-prime => 'truthy'; # OUTPUT: «True␤»
  say 4 ~~ :is-prime;             # OUTPUT: «False␤»
  ```
  
  This form can also be used to check [`Bool`](/type/Bool) values of multiple methods on the same object, such as [`IO::Path`](/type/IO/Path), by using [`Junction`](/type/Junction)s:
  
  ```raku
  say "foo" .IO ~~ :f & :rw; # OUTPUT: «False␤»
  say "/tmp".IO ~~ :!f;      # OUTPUT: «True␤»
  say "."   .IO ~~ :f | :d;  # OUTPUT: «True␤»
  ```
  
  ## [method antipair](#class_Pair "go to top of document")[§](#method_antipair "direct link")
  
  ```raku
  method antipair(Pair:D: --> Pair:D)
  ```
  
  Returns a new `Pair` object with key and value exchanged.
  
  ```raku
  my $p = (d => 'Raku').antipair;
  say $p.key;         # OUTPUT: «Raku␤»
  say $p.value;       # OUTPUT: «d␤»
  ```
  
  ## [method key](#class_Pair "go to top of document")[§](#method_key "direct link")
  
  ```raku
  multi method key(Pair:D:)
  ```
  
  Returns the *key* part of the `Pair`.
  
  ```raku
  my $p = (Raku => "d");
  say $p.key; # OUTPUT: «Raku␤»
  ```
  
  ## [method value](#class_Pair "go to top of document")[§](#method_value "direct link")
  
  ```raku
  multi method value(Pair:D:) is rw
  ```
  
  Returns the *value* part of the `Pair`.
  
  ```raku
  my $p = (Raku => "d");
  say $p.value; # OUTPUT: «d␤»
  ```
  
  ## [infix cmp](#class_Pair "go to top of document")[§](#infix_cmp "direct link")
  
  ```raku
  multi infix:<cmp>(Pair:D, Pair:D)
  ```
  
  The type-agnostic comparator; compares two `Pair`s. Compares first their *key* parts, and then compares the *value* parts if the keys are equal.
  
  ```raku
  my $a = (Apple => 1);
  my $b = (Apple => 2);
  say $a cmp $b; # OUTPUT: «Less␤»
  ```
  
  ## [method fmt](#class_Pair "go to top of document")[§](#method_fmt "direct link")
  
  ```raku
  multi method fmt(Pair:D: Str:D $format --> Str:D)
  ```
  
  Takes a *format string*, and returns a string the *key* and *value* parts of the `Pair` formatted. Here's an example:
  
  ```raku
  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␤»
  ```
  
  For more about format strings, see [sprintf](/routine/sprintf).
  
  ## [method kv](#class_Pair "go to top of document")[§](#method_kv "direct link")
  
  ```raku
  multi method kv(Pair:D: --> List:D)
  ```
  
  Returns a two-element [`List`](/type/List) with the *key* and *value* parts of `Pair`, in that order. This method is a special case of the same-named method on [`Hash`](/type/Hash), which returns all its entries as a list of keys and values.
  
  ```raku
  my $p = (Raku => "d");
  say $p.kv[0]; # OUTPUT: «Raku␤»
  say $p.kv[1]; # OUTPUT: «d␤»
  ```
  
  ## [method pairs](#class_Pair "go to top of document")[§](#method_pairs "direct link")
  
  ```raku
  multi method pairs(Pair:D:)
  ```
  
  Returns a list of one `Pair`, namely this one.
  
  ```raku
  my $p = (Raku => "d");
  say $p.pairs.^name; # OUTPUT: «List␤»
  say $p.pairs[0];    # OUTPUT: «Raku => d␤»
  ```
  
  ## [method antipairs](#class_Pair "go to top of document")[§](#method_antipairs "direct link")
  
  ```raku
  multi method antipairs(Pair:D:)
  ```
  
  Returns a [`List`](/type/List) containing the [antipair](/type/Pair#method_antipair) of the invocant.
  
  ```raku
  my $p = (d => 'Raku').antipairs;
  say $p.^name;                                     # OUTPUT: «List␤»
  say $p.first;                                     # OUTPUT: «Raku => d␤»
  say $p.first.^name;                               # OUTPUT: «Pair␤»
  ```
  
  ## [method invert](#class_Pair "go to top of document")[§](#method_invert "direct link")
  
  ```raku
  method invert(Pair:D: --> Seq:D)
  ```
  
  Returns a [`Seq`](/type/Seq). If the `.value` of the invocant is *NOT* an [`Iterable`](/type/Iterable), the [`Seq`](/type/Seq) will contain a single `Pair` whose `.key` is the `.value` of the invocant and whose `.value` is the `.key` of the invocant:
  
  ```raku
  :foo<bar>.invert.raku.say; # OUTPUT: «(:bar("foo"),).Seq␤»
  ```
  
  If invocant's `.value` *is* an [`Iterable`](/type/Iterable), the returned [`Seq`](/type/Seq) will contain the same number of `Pair`s as items in the `.value`, with each of those items a `.key` of a pair and the `.key` of the invocant the `.value` of that pair:
  
  ```raku
  :foo<Raku is great>.invert.raku.say;
  # OUTPUT: «(:Raku("foo"), :is("foo"), :great("foo")).Seq␤»
  
  :foo{ :42a, :72b }.invert.raku.say;
  # OUTPUT: «((:a(42)) => "foo", (:b(72)) => "foo").Seq␤»
  ```
  
  To perform the exact `.key` and `.value` swap, use [`.antipair` method](/type/Pair#method_antipair).
  
  ## [method keys](#class_Pair "go to top of document")[§](#method_keys "direct link")
  
  ```raku
  multi method keys(Pair:D: --> List:D)
  ```
  
  Returns a [`List`](/type/List) containing the [key](/type/Pair#method_key) of the invocant.
  
  ```raku
  say (Raku => "d").keys;                           # OUTPUT: «(Raku)␤»
  ```
  
  ## [method values](#class_Pair "go to top of document")[§](#method_values "direct link")
  
  ```raku
  multi method values(Pair:D: --> List:D)
  ```
  
  Returns a [`List`](/type/List) containing the [value](/type/Pair#method_value) of the invocant.
  
  ```raku
  say (Raku => "d").values;                         # OUTPUT: «(d)␤»
  ```
  
  ## [method freeze](#class_Pair "go to top of document")[§](#method_freeze "direct link")
  
  ```raku
  method freeze(Pair:D:)
  ```
  
  Makes the *value* of the `Pair` read-only, by removing it from its [Scalar container](/language/containers#Scalar_containers), and returns it.
  
  ```raku
  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)␤»
  ```
  
  **NOTE:** this method is deprecated as of **6.d** language version. Instead, create a new `Pair`, with a [decontainerized](/language/glossary#decont) key/value.
  
  ```raku
  $p.=Map.=head.say;                                    # OUTPUT: «orange␤»
  
  ```
  
  ## [method Str](#class_Pair "go to top of document")[§](#method_Str "direct link")
  
  ```raku
  multi method Str(Pair:D: --> Str:D)
  ```
  
  Returns a string representation of the invocant formatted as *key ~ \t ~ value*.
  
  ```raku
  my $b = eggs => 3;
  say $b.Str;                                       # OUTPUT: «eggs  3␤»
  ```
  
  ## [method Pair](#class_Pair "go to top of document")[§](#method_Pair "direct link")
  
  ```raku
  method Pair()
  ```
  
  Returns the invocant `Pair` object.
  
  ```raku
  my $pair = eggs => 3;
  say $pair.Pair === $pair;                         # OUTPUT: «True␤»
  ```
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Pair`
  
  
  
  raku-type-graph
  
  
  
  Pair
  Pair
  
  
  Any
  Any
  
  
  Pair->Any
  
  
  
  Associative
  Associative
  
  
  Pair->Associative
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  [Expand chart above](/assets/typegraphs/Pair.svg)
  