In Perl6, operators subroutines and methods have a singular purpose for a given name.
In the case of the infix +
operator it is to add two numbers. So if it is given something that is not a number it tries to turn it into a number before adding.
In the case of the .invert
method, its fundamental purpose is to invert a Pair object. That is swap the .key
and the .value
of a Pair.
So everywhere that .invert
can be used, it does so in the way that is most like inverting a Pair object.
On a Pair object with a singular .value
, it swaps the key and the value.
say ('a' => 'A').invert;
# (A => a)
If the .value
is not singular it gives you a sequence where each value is now the key of its own Pair.
say ('a' => ('A', 'B')).invert;
# (A => a B => a)
Note that .invert
always returns a sequence to be consistent. Even on that first example.
On a Hash it does it on all of the key / value pairs.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort;
# (A => 1 A => a B => a B => b)
On a List, it could do it one of two ways.
It could use the index as the key, exactly like .antipairs
does.
say ( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).antipairs.sort;
# ((1 => A) => 2 (a => (A B)) => 0 (b => B) => 1)
say ( 'a', 'b', 'c' ).antipairs;
# (a => 0 b => 1 c => 2)
It could go through each of the Pairs in the list like it currently does.
say ( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort
(A => 1 A => a B => a B => b)
Since .antipairs
already works like .pairs
except the opposite, there is really no reason for .invert
to also work like it. That would have also made .invert
less like a Pair method.
This also has the nice effect that you can get the Pairs from a Hash as a list then call .invert
on it, and it will work like just calling .invert
on the Hash directly.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.sort;
# (A => 1 A => a B => a B => b)
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).list.invert.sort;
# (A => 1 A => a B => a B => b)
It also means that you can call .invert
several times and it stays consistent.
say %( 'a' => ('A','B'), 'b' => 'B', 1 => 'A' ).invert.invert.invert.sort;
# (A => 1 A => a B => a B => b)