Контейнеры
Scalar
также используются для обозначения предметов и, следовательно, предотвращения их сплющивания.В отсутствие ограничения типа реализация будет консервативно оборачивать входящий аргумент в контейнер Scalar
только для чтения, чтобы избежать неожиданного сглаживания.Сравните это:
sub foo($x) {
my @a = $x;
say @a.elems;
}
foo([1,2,3]);
Который выводит 1 (без выравнивания) с привязкой без сигил:
sub foo(\x) {
my @a = x;
say @a.elems;
}
foo([1,2,3])
Который выводит 3, так как контекст элемента не накладывается.Если бы контейнер Scalar
отсутствовал, оба выдали бы 3.
При наличии ограничения, отличного от Iterable
, эта упаковка будет опущена.Таким образом, запись:
sub f1(Int $x) {
say $x.VAR.WHAT;
say $x.WHAT;
say $x
}
f1(1)
Будет выводить:
(Int)
(Int)
1
С .VAR
просто выдачей идентификатора для не контейнера.