Что делает $(…)
, это превращает значение в item
.
(Значение в скалярной переменной ($a
) также помечается как элемент)
say flat (1,2, (3,4) );
# (1 2 3 4)
say flat (1,2, $((3,4)) );
# (1 2 (3 4))
say flat (1,2, item((3,4)) );
# (1 2 (3 4))
По сути, это предотвращает сглаживание значения. Причина его существования в том, что Perl 6 не сглаживает списки так сильно, как большинство других языков, и иногда вам нужно немного больше контролировать выравнивание.
Следующая только сортировка делает то, что вы хотите
my \a = $ = 3;
Обнаженная $
является анонимной state
переменной.
my \a = (state $) = 3;
Проблема появляется, когда вы выполняете один и тот же бит кода более одного раза.
sub foo ( $init ) {
my \a = $ = $init; # my \a = (state $) = $init;
(^10).map: {
sleep 0.1;
++a
}
}
.say for await (start foo(0)), (start foo(42));
# (43 44 45 46 47 48 49 50 51 52)
# (53 54 55 56 57 58 59 60 61 62)
# If foo(42) beat out foo(0) instead it would result in:
# (1 2 3 4 5 6 7 8 9 10)
# (11 12 13 14 15 16 17 18 19 20)
Обратите внимание, что переменная является общей для вызовов.
Первый Promise останавливается при вызове sleep
, а затем второй устанавливает переменную состояния перед первым запуском ++a
.
Если вместо этого вы используете my $
, теперь он работает правильно.
sub foo ( $init ) {
my \a = my $ = $init;
(^10).map: {
sleep 0.1;
++a
}
}
.say for await (start foo(0)), (start foo(42));
# (1 2 3 4 5 6 7 8 9 10)
# (43 44 45 46 47 48 49 50 51 52)
Дело в том, что сигиловые « переменные » на самом деле не являются переменными (они не меняются), они больше похожи на лексически ограниченные (не) константы.
constant \foo = (1..10).pick; # only pick one value and never change it
say foo;
for ^5 {
my \foo = (1..10).pick; # pick a new one each time through
say foo;
}
По сути, весь их смысл в том, чтобы быть как можно ближе к значению, которое вы ему присваиваете. (Static Single Assignment)
# these work basically the same
-> \a {…}
-> \a is raw {…}
-> $a is raw {…}
# as do these
my \a = $i;
my \a := $i;
my $a := $i;
Обратите внимание, что выше я написал следующее:
my \a = (state $) = 3;
Обычно в объявлении состояния var присваивание происходит только при первом запуске кода. Голый $
не имеет декларации как таковой, поэтому я должен был предотвратить такое поведение, поместив декларацию в скобках.
# bare $
for (5 ... 1) {
my \a = $ = $_; # set each time through the loop
say a *= 2; # 15 12 9 6 3
}
# state in parens
for (5 ... 1) {
my \a = (state $) = $_; # set each time through the loop
say a *= 2; # 15 12 9 6 3
}
# normal state declaration
for (5 ... 1) {
my \a = state $ = $_; # set it only on the first time through the loop
say a *= 2; # 15 45 135 405 1215
}