Метод sort
возвращает Список из пар.
Поскольку вызов .kv
в списке возвращает список из index, Pair
списков, который вам не нужен; вы не можете просто вызвать .kv
. Таким образом, вам нужно отдельно извлечь ключ и значение из объектов Pair в списке, вызвав метод .kv
для каждого из них, что и делает >>.kv
.
Вместо этого вы могли бы также использовать .map(*.kv)
.
Синтаксис >>.kv
позволяет реализации распределять работу по нескольким потокам, если это имеет смысл.
(В настоящее время Rakudo просто выполняет работу в полуслучайном порядке, чтобы предотвратить неправильное использование этой функции)
Существует альтернативный способ написания цикла путем извлечения атрибутов с помощью наречий в субсигнатуре:
for %hash.sort -> (:$key, :$value) {
say "'$key' => '$value'";
}
for %hash.sort -> $pair (:$key, :$value) {
say $pair;
say $key === $pair.key and $value === $pair.value; # True
}
# :$key is short for :key($key)
for %hash.sort -> (:key($k), :value($v)) {
say "'$k' => '$v'";
}
Это может быть полезно для других объектов, у которых нет метода для создания списка их общедоступных атрибутов.
class C { has $.a; has $.b; has $.c; has $!private-value }
my $c = 5;
my $obj = C.new(:a<A>,:b(1),:$c);
given $obj -> ( :$a, :b($b), :$c) ) {
say "$a $b $c";
}
# ignore $.a by using an unnamed scalar
given $obj -> ( :a($), :$b, :$c ) { ... }
# places any unspecified public attributes in %others
given $obj -> ( :$a, :$b, *%others ) {
.say for keys %others; # c
}
# ignores any unspecified attributes
# useful to allow subclasses to add more attributes
# or to just drop any values you don't care about
given $obj -> ( :$a, :$b, *% ) { ... }
# fails because it doesn't handle the public c attribute
# in the sub-signature
given $obj -> ( :$a, :$b ) { ... }
Это только начало того, что возможно с подписями.
Все следующее также разрешено в сигнатурах подпрограмм и методов, необязательных и полностью излишних для этого примера. Это действительно полезно в нескольких подпрограммах и нескольких методах для ограничения возможных кандидатов.
for 'one' => 1, 1/3
->
# Type is an alias to the object type
::Type Any $_ # Any is the default type requirement
# the public attributes of the object
(
::A-Type Any :key( :numerator( $a ) ),
::B-Type Any :value( :denominator( $b ) ) where $b >= 1,
)
{
my Type $obj = $_; # new variable declared as having the same type
my A-Type $new-a = $a;
my B-Type $new-b = $b;
# could have used $_.^name or .^name instead of Type.^name
# so you don't actually have to add the alias to the signature
# to get the name of the arguments type
say Type.^name, ' ', $_;
say ' ', A-Type.^name, ' ', $a;
say ' ', B-Type.^name, ' ', $b;
}
Pair one => 1
Str one
Int 1
Rat 0.333333
Int 1
Int 3
Что касается использования .sort({.key})
, да, это в основном то же самое, что и sort
принимает все Вызывается там.
Я хотел бы отметить, что вам даже не нужно было указывать аргумент для sort
, потому что это default еще умнее, чем то, что вы ему дали.
В Perl 6 есть много способов создания и доступа к объектам Callable. Таким образом, любое из следующего сработало бы:
*.key
{ .key } # { $_.key }
-> $_ { .key } # basically what the previous line turns into
{ $^placeholder-var.key }
sub ($_) { .key }
&a-subroutine-reference # you would have to create the subroutine though
Кроме того, поскольку все обычные операторы на самом деле являются подпрограммами, вы можете использовать их в других местах, где вам нужен Callable а>. (Хотя я не могу придумать ни одного, который работал бы в этом месте)
&infix:<+> # the subroutines responsible for the numeric addition operator
&[+] # ditto
&prefix:<++>
&postfix:<++>
# etc
person
Brad Gilbert
schedule
31.07.2015