Краткий ответ: my
помечает переменную как частную в лексической области, а local
помечает переменную как частную в динамической области.
Проще понять my
, так как это создает локальную переменную в обычном смысле. Создана новая переменная, и она доступна только внутри заключительного лексического блока, который обычно отмечается фигурными скобками. Есть несколько исключений из правила фигурных скобок, таких как:
foreach my $x (@foo) { print "$x\n"; }
Но это всего лишь Perl, который делает то, что вы имеете в виду. Обычно у вас есть что-то вроде этого:
sub Foo {
my $x = shift;
print "$x\n";
}
В этом случае $x
является частным для подпрограммы, и ее область действия заключена в фигурные скобки. Следует отметить, что в отличие от local
, область действия переменной my
определяется по отношению к вашему коду, как он написан в файле. Это феномен времени компиляции.
Чтобы понять local
, вам нужно думать о стеке вызовов вашей программы во время ее работы. Когда переменная local
, она переопределяется с точки, в которой оператор local
выполняется для всего, что находится ниже стека, до тех пор, пока вы не вернете обратно стек в вызывающую сторону блока, содержащего local
.
Поначалу это может сбить с толку, поэтому рассмотрим следующий пример.
sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }
$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect
Когда foo
вызывается в первый раз, он видит глобальное значение $x
, которое равно 1. Когда вызывается bar
и выполняется local $x
, это переопределяет глобальное $x
в стеке. Теперь, когда foo
вызывается из bar
, он видит новое значение 2 для $x
. Пока что это не очень особенное, потому что то же самое произошло бы без вызова local
. Волшебство в том, что когда bar
возвращается, мы выходим из динамической области, созданной local $x
, и предыдущий глобальный $x
возвращается в область. Таким образом, для последнего вызова foo
, $x
равно 1.
Вы почти всегда захотите использовать my
, так как это даст вам локальную переменную, которую вы ищете. Однажды в голубой луне, local
действительно удобно делать крутые вещи.