Ответ Эрика Строма правильный, и, вероятно, то, что вы хотели увидеть, но не вдаваться в детали привязки.
Краткое примечание о лексической продолжительности жизни: лексики создаются во время компиляции и фактически доступны даже до ввода их области действия, как показано в этом примере:
my $i;
BEGIN { $i = 42 }
print $i;
После этого, когда они выходят из области видимости, они становятся недоступными до следующего раза, когда они попадают в область видимости:
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();
В вашем коде замыкание привязано к исходному лексическому $i
во время компиляции.
Однако циклы foreach немного странные; в то время как my $i
фактически создает лексику, цикл foreach не использует его; вместо этого он связывает его с одним из зацикленных значений на каждой итерации, а затем восстанавливает его в исходное состояние после цикла. Таким образом, ваше закрытие является единственной ссылкой на оригинальную лексику $i
.
Небольшое изменение показывает большую сложность:
foreach (@foo) {
my $i = $_;
sub printer {
my $blah = shift @_;
print "$blah-$i\n";
}
printer("test");
}
Здесь исходный $i
создается во время компиляции, и замыкание связывается с этим; первая итерация цикла устанавливает его, но вторая итерация цикла создает новый $i
, не связанный с замыканием.