Perl содержит множество магических переменных (также "специальные" или "системные"), которые влияют на исполнение программы:
$_ — переменная по умолчанию для многих операторов (foreach, map, grep, while <> и др.).@_ — массив входящих аргументов внутри подпрограмм.%SIG — хэш с обработчиками сигналов ОС.my @nums = (1,2,3); foreach (@nums) { $_ *= 2; # изменяется оригинальный массив! } sub show_args { print "First: ", $_[0], " "; } show_args('a','b'); # $_[0] = 'a' $SIG{INT} = sub { print "Caught Ctrl-C "; exit; };
Осторожно: многие магические переменные изменяются неявно; неправильное обращение может повлиять на глобальное состояние программы.
Можно ли безопасно использовать глобальную переменную $_ в нескольких вложенных циклах или подпрограммах?
Ответ: Нет, т.к. вложенный цикл или подпрограмма часто перезаписывает $_, что приводит к потере значения во внешнем контексте. Рекомендуется использовать явные переменные:
foreach my $x (@a) { foreach my $y (@b) { ... } }
История
В скрипте для обработки больших логов был использован цикл while(<FH>) {...}. Внутри цикла вызывалась функция, которая, в свою очередь, запускала map без собственного указания переменной, что испортило $_ во внешнем цикле, приводя к пропуску строк.
История
При обработке сигналов через %SIG, разработчик подменил обработчик __DIE__, но не учел, что это влияет на поведение всего процесса, включая сторонние модули, и получил неуправляемое завершение при ошибках в чужом коде.
История
Оптимизация передачи аргументов через ссылку на массив (@_) внутри подпрограммы и попытка изменить её значения напрямую без явного копирования приводила к неожиданному изменению переменных во внешнем коде.