Чем $ _ отличается от именованных аргументов ввода или цикла?

StackOverflow https://stackoverflow.com/questions/5405423

  •  29-10-2019
  •  | 
  •  

Вопрос

Поскольку я много использую $ _, я хочу лучше понять его использование. $ _ - это глобальная переменная для неявных значений, насколько я понял и использовал.

Поскольку $ _, похоже, все равно установлен, есть ли причины использовать именованные переменные цикла вместо $ _ помимо удобочитаемости?

В каких случаях имеет значение, что $ _ является глобальной переменной?

Итак, если я использую

родовое слово

или даже

родовое слово

действует так же, как

родовое слово

Но работает ли он так же? Я думаю, это не совсем так, но каковы фактические различия?

Обновление :

Похоже, что в этом примере $ _ даже правильно определена. Это больше не глобально? Я использую 5.12.3.

родовое слово

, который печатает правильно 1234один1234два1234три1234четыре.

Для глобального $ _ я ожидал бы 1234 4 1234 4 1234 4 1234 4 .. или я упустил что-то очевидное?

Когда тогда $ _ станет глобальным?

Обновление :

Хорошо, прочитав различные ответы и более внимательно прочитав perlsyn, я пришел к выводу:

Помимо удобочитаемости, лучше избегать использования $ _, поскольку неявная локализация $ _ должна быть известна и учтена, иначе можно столкнуться с неожиданным поведением.

Спасибо за разъяснения по этому поводу.

Это было полезно?

Решение

родовое слово

Проблема не в том, названы они или нет.Проблема в том, являются ли они «переменными пакета» или «лексическими переменными».

См. очень хорошее описание двух систем переменных, используемых в Perl «Coping with Scoping»:

http://perl.plover.com/FAQs/Namespaces.html

переменные пакета являются глобальными переменными, поэтому их следует избегать по всем обычным причинам (например, действия на расстоянии).

Избегание переменных пакета - это вопрос "правильной работы" или "труднее вводить ошибки", а не "удобочитаемости".

родовое слово

Везде.

Лучший вопрос:

родовое слово

Есть несколько мест, где Perl будет использовать local () ize $ _ для вас, в первую очередь foreach, grep и map.Все остальные места требуют, чтобы вы локально () использовали его самостоятельно, поэтому вы будете вводить потенциальную ошибку, когда неизбежно забудете сделать это.:-)

Другие советы

Классический режим отказа при использовании кода $_ (неявно или явно) в качестве переменной цикла -

родовое слово

где, поскольку переменная цикла в for / foreach привязана к фактическому элементу списка, означает, что код while (<F>) перезаписывает код @myarray строками, считанными из файлов.

$ _ - это то же самое, что присвоение переменной имени из вашего второго примера в том виде, в котором она обычно используется.$ _ - это просто сокращенное имя переменной по умолчанию для текущего элемента в текущем цикле, чтобы сэкономить на вводе при выполнении быстрого и простого цикла.Я предпочитаю использовать именованные переменные, а не значения по умолчанию.Это проясняет, что это такое, и если мне понадобится выполнить вложенный цикл, конфликтов не будет.

Поскольку $ _ является глобальной переменной, вы можете получить неожиданные значения, если попытаетесь использовать ее значение, которое она имела из предыдущего блока кода.Новый блок кода может быть частью цикла или другой операции, которая вставляет свои собственные значения в $ _, перезаписывая то, что вы ожидали там увидеть.

Риск в использовании $ _ - это то, что он глобальный (если вы не локализуете его с local $_), и поэтому, если некоторая функция, которую вы звоните в вашем цикле, также используются $ _, два использования могут вмешаться.

по причинам, которые мне не понятны, это только иногда укусило меня, но я обычно локализую $ _, если я использую его внутри пакетов.

В $_ нет ничего особенного, кроме того, что он является параметром по умолчанию для многих функций.Если вы явно лексически ограничиваете свой $_ с помощью my, perl будет использовать локальную версию $_, а не глобальную.В этом нет ничего странного, это как и любая другая именованная переменная.

родовое слово

Вы должны быть немного озадачены выводом, пока не обнаружите, что perl сохранит исходное значение переменной цикла при выходе из цикла (см. perlsyn ).

Примечание ex2 выше.Здесь второй цикл использует код $_ с лексической областью видимости, объявленный в первом цикле.Тонко, но ожидаемо.Опять же, это значение сохраняется при выходе, поэтому два цикла не мешают.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top