Подтвердить что ты не робот

Почему Perl foreach не требует, чтобы переменная была объявлена с моим?

Сегодня я наткнулся на что-то в Perl, о котором я не знал: он "локализует" переменную, которой присвоены элементы перечисленного списка.

Это, конечно же, задокументировано в документации Perl, однако я не смог ее запомнить или прочитать.

Следующий сценарий демонстрирует, что я имею в виду:

use warnings;
use strict;

my $g = 99;

foreach $g (1..5) {
  p($g);
}

sub p {
  my $l = shift;
  printf ("%2d %2d\n", $g, $l);
}

Печать сценария

99  1
99  2
99  3
99  4
99  5

потому что $g "локализовано" в цикле foreach.

Насколько я могу судить, нет никакой разницы, если бы я добавил my к $g в цикл foreach:

foreach my $g (1..5) {

На самом деле, я закончил это, потому что я чувствую, что он дает понять, что переменная является локальной для цикла.

Теперь мой вопрос: есть ли сценарий, в котором мое использование my имеет значение (учитывая, что $g уже объявлено глобально).

4b9b3361

Ответ 1

Исследуемое поведение задокументировано в цикле Foreach в Perlsyn

Цикл foreach выполняет итерацию по обычному значению списка и устанавливает скалярную переменную VAR в качестве каждого элемента списка по очереди. Если переменной предшествует ключевое слово my, то она имеет лексическую область видимости и поэтому видна только внутри цикла.

который продолжает объяснение

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

Таким образом, не должно быть никакой разницы между тем, чтобы локализовать это с my или оставить это для foreach.

Небольшое любопытство в том, что

Эта неявная локализация происходит только в цикле foreach.

Все это дополнительно разъясняется в этом фрагменте из Частных переменных через my() из perlsub.

Цикл foreach умолчанию определяет динамическую область видимости своей индексной переменной способом local. Однако, если переменная индекса имеет префикс с ключевым словом my, или если в области уже есть лексическое слово с таким именем, то вместо этого создается новый лексический.

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

Я абсолютно поддерживаю и рекомендую (всегда) иметь my там.