Wartość przechowywane w Scalar pojemnika jest nie automatycznie powtórzyć
Choć obie $s
i $seq
są scalars (aka „zmienne”) $s
jest związana bezpośrednio do wartości Seq natomiast swojej $seq
jest związany z pośrednik Scalar (pamiętaj, wielkie litery S
) "kontener", który z kolei zawiera Seq. Wartość przechowywana w kontenerze Scalar to , a nie automatycznie iterowana, gdy jest używana z funkcjami takimi jak for
.
Bardziej szczegółowo:
my $s := 0 ... 3;
.say for $s;
Ponieważ zmienna zgłoszenie my
wykorzystuje napęd bezpośredni wiązania :=
inicjalizacji, $s
jest bezpośrednio związana z jedną wartością 0 ... 3
Sekw.
Oznacza to, że instrukcja for
widzi pojedynczą wartość Seq, określa, że spełnia rolę Iterable, i spłaszcza (iteruje).
Teraz pomyśl o tym:
my $s := 0 ... 3;
my $container = $s;
.say for $container;
Ponieważ druga deklaracja my
wykorzystuje operator przypisania =
inicjalizacji, nowa zmienna $container
najpierw związany z nowym Scalar pojemniku, który następnie „zawiera” cokolwiek zostanie przydzielony.
Zgodnie z językiem szeroko Slurpy Conventions (w szczególności: „An iterowalny wewnątrz skalarnym pojemniku nie liczy”), A for
oświadczenie nie iteracji wartość posiadanych w skalarnym pojemnika, więc linia .say for $container
robi tylko jeden say
.
Podobna sytuacja dotyczy oryginalnej procedury show
, ponieważ deklaracje parametrów zmiennych są domyślnie kontenerami (semantycznymi).
Jedną z opcji jest zamiast dodać is raw
cechę do parametru $seq
:
sub show ($seq is raw) { .say for $seq }
Zapobiega to zwykle automatyczne wiązanie $seq
do skalara pojemnika (które z kolei zawierają wartość SEQ) w ramach połączenie z show
.
Innym rozwiązaniem jest umożliwienie $seq
być zobowiązany do skalara pojemnika, lecz wyraźnie spłaszczyć (iteracji) zmienną $seq
w ciele rutyny show
użyciu prefiksu |
:
sub show ($seq) { .say for |$seq }
Dzięki! Ale tak, myślę o nieskończonych, leniwych sekwencjach. :) –