Perl zawiera wiele magicznych zmiennych (także "specjalne" lub "systemowe"), które wpływają na wykonanie programu:
$_ — zmienna domyślna dla wielu operatorów (foreach, map, grep, while <> itp.).@_ — tablica przychodzących argumentów wewnątrz podprogramów.%SIG — hasz z obsługami sygnałów systemu operacyjnego.my @nums = (1,2,3); foreach (@nums) { $_ *= 2; # zmienia oryginalną tablicę! } sub show_args { print "Pierwsza: ", $_[0], " "; } show_args('a','b'); # $_[0] = 'a' $SIG{INT} = sub { print "Przechwycono Ctrl-C "; exit; };
Uwaga: wiele magicznych zmiennych zmienia się niejawnie; niewłaściwe odniesienie może wpłynąć na globalny stan programu.
Czy można bezpiecznie używać globalnej zmiennej $_ w kilku zagnieżdżonych pętlach lub podprogramach?
Odpowiedź: Nie, ponieważ zagnieżdżona pętla lub podprogram często nadpisuje $_, co prowadzi do utraty wartości w zewnętrznym kontekście. Zaleca się użycie jawnych zmiennych:
foreach my $x (@a) { foreach my $y (@b) { ... } }
Historia
W skrypcie do przetwarzania dużych logów użyto pętli while(<FH>) {...}. Wewnątrz pętli wywoływana była funkcja, która z kolei uruchamiała map bez własnego wskazania zmiennej, co zepsuło $_ w zewnętrznej pętli, prowadząc do pominięcia wierszy.
Historia
Podczas przetwarzania sygnałów przez %SIG, programista podmienił obsługę __DIE__, ale nie uwzględnił, że wpływa to na zachowanie całego procesu, w tym zewnętrznych modułów, i doświadczył niekontrolowanego zakończenia przy błędach w cudzym kodzie.
Historia
Optymalizacja przekazywania argumentów przez referencję do tablicy (@_) wewnątrz podprogramu i próba zmiany jej wartości bez jawnego kopiowania prowadziły do niespodziewanej zmiany zmiennych w kodzie zewnętrznym.