odpowiedź
Erica Strom jest poprawna, i prawdopodobnie to co Cię chciałem zobaczyć, ale nie wchodzę w szczegóły wiązania.
Krótka notatka o leksykalnym żywotność: lexicals są tworzone w czasie kompilacji i są faktycznie dostępne jeszcze przed wprowadzeniem ich zakres, jak w poniższym przykładzie:
my $i;
BEGIN { $i = 42 }
print $i;
Następnie, gdy udają się poza zakresem, oni stają się niedostępne aż do chwili, gdy będą w zakresie:
print i();
{
my $i;
BEGIN { $i = 42 }
# in the scope of `my $i`, but doesn't actually
# refer to $i, so not a closure over it:
sub i { eval '$i' }
}
print i();
w kodzie, zamknięcie jest zobowiązany do wstępnej leksykalnej $i
w czasie kompilacji. Jednak pętle foreach są trochę dziwne; podczas gdy my $i
faktycznie tworzy leksykalny, pętla foreach go nie używa; zamiast tego przypisuje ją do jednej z zapętlonych wartości każdej iteracji, a następnie przywraca jej pierwotny stan po pętli. Twoje zamknięcie jest więc jedyną rzeczą odwołującą się do oryginalnego leksykalnego $i
.
Nieznaczne wahania pokazuje więcej Złożoność:
foreach (@foo) {
my $i = $_;
sub printer {
my $blah = shift @_;
print "$blah-$i\n";
}
printer("test");
}
Tutaj oryginalny $i
jest tworzony w czasie kompilacji i zamknięcie wiąże się z tym; pierwsza iteracja pętli ustawia ją, ale druga iteracja pętli tworzy nową $i
, która nie jest powiązana z zamknięciem.
bardzo interesujące, dziękuję – Snark