Область видимости переменных в Perl
В Perl существует два основных типа переменных. Один из них - это глобальные переменные модуля, объявленные либо с помощью ныне устаревшей конструкции use vars, либо с помощью our.
Другой тип - это лексические переменные, объявленные с помощью my.
Давайте посмотрим, что происходит, когда мы объявляем переменную с помощью my. В каких местах кода переменная будет доступна? Другими словами, где будет область видимости переменной?
Область видимости: содержащий блок
#!/usr/bin/perl use strict; use warnings; { my $email = 'foo@bar.com'; print "$email\n"; # foo@bar.com } # print $email; # $email не существует # Global symbol "$email" requires explicit package name at ...
Внутри безымянного блока (пара фигурных скобок {}) мы видим объявление новой переменной "$email". Эта переменная существует на участке между ее объявлением и концом блока. Вот почему строка после закрывающей скобки } закомментирована. Если убрать # из строки # print $email; и попробовать запустить скрипт, мы получим ошибку компиляции: Global symbol "$email" requires explicit package name at ....
Другими словами, область видимости переменной, объявленной с помощью my ограничивается содержащим ее блоком.
Область видимости: видимый везде
Переменная $lname объявлена в начале кода. Она будет видима везде до конца файла. Даже внутри блоков. Даже если эти блоки являются объвлениями функций. Если мы изменим переменную внутри блока, ее значение изменится и в остальном коде. Даже если вы выйдете из блока:
#!/usr/bin/perl use strict; use warnings; my $lname = "Bar"; print "$lname\n"; # Bar { print "$lname\n"; # Bar $lname = "Other"; print "$lname\n"; # Other } print "$lname\n"; # Other
Переменная, скрытая другим объявлением
#!/usr/bin/perl use strict; use warnings; my $fname = "Foo"; print "$fname\n"; # Foo { print "$fname\n"; # Foo my $fname = "Other"; print "$fname\n"; # Other } print "$fname\n"; # Foo
В этом случае переменная $fname объвлена в начале кода. Как сказано выше, она будет видима везде до конца файла, за исключением мест, где она будет "скрыта" локально объявленной переменной с таким же именем.
Внутри блока мы объявли с помощью my другую переменную с таким же именем. По сути, это скроет переменную $fname, объявленную снаружи блока, пока мы не покинем блок. В конце блока (}) переменная $fname, объявленная внутри него, будет уничтожена, а первоначальная $fname снова станет доступна. Эта особенность особенно важна, так как она дает возможность создавать переменные внутри небольших блоков, не задумываясь о возможном использовании такого же имени снаружи блока.
Одинаковые имена в разных блоках
Вы можете спокойно использовать одинаковые имена переменных в разных блоках. Эти переменные не будут никак связаны друг с другом.
#!/usr/bin/perl use strict; use warnings; { my $name = "Foo"; print "$name\n"; # Foo } { my $name = "Other"; print "$name\n"; # Other }
объявление в модуле внутри файла
Это немного более продвинутый пример, и, возможно, здесь стоит обратить внимание:
Perl позволяет переключаться между пространствами имен внутри одного файла с помощью ключевого слова package. Объявление модуля с помощью package НЕ создает область видимости. Если вы объявите переменную, явно указав пространство имен с помощью package main, которое и по умолчанию является телом вашего скрипта, то ваша переменная $fname все равно будет видима в этом файле, даже в других пространствах имен.
Если вы объявите переменную "$lname" в пространстве имен "Other", она будет видима, если потом вы переключитесь обратно на пространство имен main. Если же объявление package Other было в другом файле, то переменные, объявленные там, будут находиться в другой области видимости, созданной файлом.
#!/usr/bin/perl use strict; use warnings; my $fname = "Foo"; print "$fname\n"; # Foo package Other; use strict; use warnings; print "$fname\n"; # Foo my $lname = 'Bar'; print "$lname\n"; # Bar package main; print "$fname\n"; # Foo print "$lname\n"; # Bar
Published on 2013-07-09