Jedną z pierwszych rzeczy, których próbuję się nauczyć w obcym języku programowania, jest to, jak radzi sobie z zamknięciami. Ich semantyka często przeplata się z tym, w jaki sposób język obsługuje zakresy i różne inne podstępne elementy, więc ich zrozumienie ujawnia kilka innych aspektów tego języka. Dodatkowo, zamknięcia są naprawdę mocną konstrukcją i często ograniczają ilość płytek, które muszę wpisać. Więc ja bawić z zamknięciami Perl i natknąłem się na małą Gotcha:
my @closures;
foreach (1..3) {
# create some closures
push @closures, sub { say "I will remember $_"; };
}
foreach (@closures) {
# call the closures to see what they remember
# the result is not obvious
&{$_}();
}
Kiedy pisałem powyższy kod Spodziewałem się zobaczyć
I will remember 1
I will remember 2
I will remember 3
lecz mam I will remember CODE(0x986c1f0)
.
Powyższy eksperyment ujawnił, że $_
jest bardzo zależny od kontekstu i jeśli pojawia się w zamknięciu, to jego wartość nie jest ustalona w momencie tworzenia zamknięcia. Zachowuje się bardziej jak odniesienie. Jakie inne pomysły powinienem mieć świadomość przy tworzeniu zamknięć w perlu?
Ale to prawie to samo, co użycie 'foreach my $ num ...'. – davidk01
Więc jeśli zamykają się tylko na zmiennych leksykalnych, co dzieje się z innymi rodzajami zmiennych? Czy zamknięcie korzysta z wartości dostępnej w witrynie połączenia, tak jak ma to miejsce w przypadku '$ _'? – davidk01
@ davidk01: jak w każdym innym języku programowania, który dopuszcza zmienne globalne, zamknięcia faktycznie zbliżają się do tej zmiennej, tak jak zwykle. Po prostu zapomniałeś, że jest on globalny i dlatego może się zmienić, gdy inny kod ustawia swoją wartość na coś innego (np. Przez anonimowy sub, gdy się go nazywa). – slebetman