W Perl zasięg zmiennych definiowany jest przez słowa kluczowe my i local.
my tworzy zmienną z leksykalnym zasięgiem (działa tylko w bieżącym bloku).local tymczasowo przechowuje bieżącą wartość zmiennej globalnej i ustawia nową na czas istnienia bloku — zazwyczaj używany tylko z zmiennymi globalnymi (np. $_, $/ itp.).Przykład:
my $x = 42; # widoczne tylko w bieżącym bloku { local $/ = undef; my $input = <STDIN>; # $/ tutaj undef, po bloku - przywróci wartość }
Używanie my jest preferowane z powodu bardziej przewidywalnego zasięgu.
Co się stanie, gdy użyjemy my i local z tą samą zmienną, zadeklarowaną w dwóch różnych blokach?
Często odpowiadają, że
localimydziałają tak samo, ale to nieprawda.localdziała tylko z zmiennymi globalnymi (zmiennymi pakietowymi). Zmienna zadeklarowana za pomocąmyjest niewidoczna dlalocal.
Przykład:
our $foo = "global"; { local $foo = "local"; print $foo; # "local" } print $foo; # "global" { my $foo = "lexical"; } # $foo poza blokiem - wersja globalna, nie "lexical"
Historia
W skrypcie użyto local do tymczasowej podmianki zmiennej, zadeklarowanej przez my, co nie prowadziło do żadnych rezultatów i powodowało błędy w przetwarzaniu zdarzeń w jednym z wewnętrznych modułów.
Historia
W projekcie "zlokalizowano" $_ przez local wewnątrz foreach, oczekując na podmianę $_ dla iteratorów, zapominając, że foreach już ustawia nowe $_. Wynik - nie działający filtr i błędna logika iteracji.
Historia
Globalna zmienna pakietowa nie była zadeklarowana przez our, a próba lokalizacji przez local $var prowadziła do awarii skryptu z powodu strict i warning, a debugowanie zajęło cały dzień.