for
не l oop сверх детализированных значений.
Когда вы помещаете что-то в скалярный контейнер, оно детализируется.
sub foo ( $v ) { # itemized
for $v { .say }
}
sub bar ( \v ) {
for v { .say }
}
foo (1,2,3);
# (1 2 3)
bar (1,2,3);
# 1
# 2
# 3
Элемент в Ха sh также является скалярным контейнером.
my %h = 'foo' => 'bar';
say %h<foo>.VAR.^name;
# Scalar
Так что если вы поместите список в Ха sh, он будет детализирован.
my %h;
my \list = (1,2,3);
%h<list> = list;
say list.VAR.^name;
# List
say %h<list>.VAR.^name;
# Scalar
Поэтому, если вы хотите, чтобы l oop превышало значения, вы должны удалить его из списка.
%h<list>[]
%h<list><>
%h<list>.list
%h<list>.self
@(%h<list>)
given %h<list> -> @list { … }
my @list := %h<list>;
(my @ := %h<list>) # inline version of previous example
Вы можете избежать этого скалярного контейнера, связавшись вместо него.
%h<list> := list;
(Это не позволяет оператору =
работать с этим элементом ha sh.)
Если вы заметили, что в объекте класса вы определили его с @
not $
class R1 {
has Str $.some-str is required;
has @.some-list is required;
}
Если вы изменили его на $
и отметили его rw
, он будет работать как пример Ha sh
class R2 {
has Str $.some-str is required;
has List $.some-list is required is rw;
}
my $r2 = R2.new(
some-str => '…',
some-list => (1,2,3),
);
for $r2.some-list { .say }
# (1 2 3)
Это должна быть переменная $
или не будет в скалярном контейнере.
Он также должен быть помечен rw
, чтобы метод доступа возвращал реальный скалярный контейнер, а не детализированное значение.