Я бы сказал, что это:
нарушение передового опыта с вашей стороны (всегда используйте как локальную переменную как возможную область и избегайте использования $_
только из-за проблемы, с которой вы столкнулись)
в сочетании с ошибка в API , вызванная тем же нарушением лучших практик, а также не локализации специальной переменной с local $_
, как это запрещено perldoc perlvar .
В дополнение к perldoc, API нарушает Perl Best Practices (как в правилах книги Конвея):
Раздел 5.6. Локализация переменных пунктуации
Если вы вынуждены изменить пунктуацию, локализуйте ее.
Проблемы, описанные ранее в разделе «Локализация, также могут возникать всякий раз, когда вы вынуждены изменить значение в знаке препинания (часто в операциях ввода-вывода). Все переменные пунктуации имеют глобальный характер. было бы совершенно неявным поведением в большинстве других языков: буферизация вывода, нумерация строк ввода, окончания строк ввода и вывода, индексация массива и так далее.
Обычно серьезной ошибкой является изменение переменной знака препинания без ее предварительной локализации. Нелокализованные назначения могут потенциально изменить поведение кода в совершенно не связанных частях вашей системы, даже в модулях, которые вы не написали сами, а просто используете.
Использование local - это самый чистый и надежный способ временно изменить значение глобальной переменной. Он всегда должен применяться в наименьшей возможной области видимости, чтобы минимизировать влияние любого «окружающего поведения», которое может контролировать переменная:
Вот также полная документация perldoc perlvar - поиск по слову "nasty_break" на веб-странице (я не смог найти прямую ссылку на странице, но она близка к началу страницы)
Вы должны быть очень осторожны, когда
изменение значений по умолчанию большинства
специальные переменные, описанные в этом
документ. В большинстве случаев вы хотите
локализуйте эти переменные перед
изменяя их, так как если вы этого не сделаете,
изменение может повлиять на другие модули, которые
полагаться на значения по умолчанию
специальные переменные, которые у вас есть
изменилось. Это один из правильных
способы прочитать весь файл сразу:
- открой мои $ fh, "<", "foo" или умри $!; </li>
- местный $ /; # включить режим локализованной стружки
- my $ content =;
- закрыть $ fh;
Но следующий код довольно плох:
- открой мои $ fh, "<", "foo" или умри $!; </li>
- undef $ /; # включить режим slurp
- my $ content =;
- закрыть $ fh;
, так как какой-то другой модуль, возможно, захочет
читать данные из некоторого файла в
по умолчанию «линейный режим», поэтому, если код мы
только что представлен был выполнен,
глобальное значение $ / теперь изменилось
для любого другого кода, работающего внутри
тот же интерпретатор Perl.
Обычно, когда переменная локализована
Вы хотите убедиться, что это изменение
влияет на кратчайший возможный объем.
Так что, если вы уже не в какой-то
короткий {} блок, вы должны создать его
сам. Например:
- my $ content = '';
- открой мои $ fh, "<", "foo" или умри $!; </li>
- {
- местный $ /;
- $ content =;
- }
- закрыть $ fh;
Вот пример того, как ваши собственные
код может сломаться:
- для (1..5) {
- nasty_break (); * * тысяча девяносто три
- печать "$ _";
- }
- sub nasty_break {
- $ _ = 5;
- # сделать что-то с $ _
- }
Вы, вероятно, ожидаете, что этот код
печать:
- 1 2 3 4 5
но вместо этого вы получите:
- 5 5 5 5 5
Почему?Потому что nasty_break () изменяет $ _, не локализуя его в первую очередь.Исправление заключается в добавлении local ():
- local $ _ = 5;