Widziałem ten fragment kodu w odpowiedzi na inny wpis: Why would I use Perl anonymous subroutines instead of a named one?, ale nie mogłem dokładnie określić, co się dzieje, więc chciałem go uruchomić samodzielnie.Współdzielone zmienne w kontekście podprogramów a anonimowe podprogramy
sub outer
{
my $a = 123;
sub inner
{
print $a, "\n"; #line 15 (for your reference, all other comments are the OP's)
}
# At this point, $a is 123, so this call should always print 123, right?
inner();
$a = 456;
}
outer(); # prints 123
outer(); # prints 456! Surprise!
W powyższym przykładzie, otrzymał ostrzeżenie: „Zmienna $ a nie pozostanie na wspólnej linii 15. Oczywiście, jest to, dlaczego wyjście jest«nieoczekiwane», ale nadal nie bardzo rozumiem co tu się dzieje.
sub outer2
{
my $a = 123;
my $inner = sub
{
print $a, "\n";
};
# At this point, $a is 123, and since the anonymous subrotine
# whose reference is stored in $inner closes over $a in the
# "expected" way...
$inner->();
$a = 456;
}
# ...we see the "expected" results
outer2(); # prints 123
outer2(); # prints 123
w tym samym duchu, nie rozumiem, co się dzieje w tym przykładzie albo. Może ktoś proszę wyjaśnić?
góry dziękuję.
„Przetwarzanie” to chyba niewłaściwe słowo tutaj, ale „kompilacja” wydaje się nieco źle też: IIRC, dla zamknięć z skompilowany kod jest po prostu łączony z nowym środowiskiem/zasięgiem, co daje nowe CV, podczas gdy nazwane podsystemy nigdy nie są przywracane do nowego zakresu (bez ponownego definiowania). – amon
Wielkie dzięki, to było bardzo pomocne! –