Данную статью я писала больше для себя. Поэтому, если кто-то почерпнет для себя что-нибудь полезное, я буду только рада.
Конечно, вы скажите зачем вообще нужна эта статья , если без применения директивы use strict можно спокойно пользоваться переменными $var , не указывая
точно к какому типу они относятся. Но в этом случае все переменные, определенные как $var, будут видны из любой точки Вашей программы т.е. будут являться глобальными. Вообщем статью писала для себя, так что начнем.
Объявления с лексической областью видимости действуют только от точки, где находится объявление, и до конца самой внутренней из охватывающих
областей видимости (блока , файла или eval). С помощью my создаются именно такие переменные - переменные с лексической областью видимости.
Пример 1:
#!/usr/bin/perl -w use strict; my $private=5; { #Здесь видим внутреннюю переменную my $private = 10; print "Private = $private \n"; } #Здесь видим наружную переменную print "Private = $private \n";
Результат:
Private = 10 Private = 5
Пример 2:
{ my $hello = "hello"; } print $hello;
Результат:
При компиляции будет выдана ошибка
Global symbol "$hello" requires explicit package name
Это означает, что в пакете main:: данная переменная не объявлена, а другого пакета с этой переменной Вы не указали.
Повторные объявления our не имеют смысла вложенности. Каждое вложенное my создает новую переменную, как в примере 1. Каждое вложенное local создает новое значение, как в примере 5. Всякий раз, когда используется our, речь идет о той же самой глобальной переменной без учета вложенности.
Пример 3:
#Здесь значение глобальной переменной равно 5 our $global_var=5; { #Здесь изменяем значение ТОЙ ЖЕ САМОЙ переменной на 10 our $global_var = 10; } #Теперь значение глобальной переменной равно 10 print "Global var = $global_var \n";
Пример 4:
{ package Utils; our $sum; #С глобальными переменными можно работать и внутри методов sub create_sum{ $sum = int(rand(5)) + 1; } sub printing_sum{ print $sum,"\n"; } } #Создаем random значение переменной sum Utils::create_sum; #Выводим это значение Utils::printing_sum;
Вот пример для использования local для "подмены" значения глобальной переменной.
Пример 5:
{ package Man; our $name = "Greg"; our $years = 25; my $weight = 80; } #Выдаст 25 print $Man::years,"\n"; #Выдаст ошибку "Use of uninitialized value $Man::weight" print $Man::weight,"\n"; #Выдаст исходное имя Greg print $Man::name,"\n"; sub func{ #Выдаст текущее число лет print "our var = ", $Man::years, "\n"; local $Man::name = "James"; #Выдаст временное значение имени James print "local var = ",$Man::name, "\n"; #Увеличиваем значение глобальной переменной foreach (1, 2, 3, 4) { $Man::years+= 1; } } func; func; #Теперь число лет 33 print $Man::years,"\n"; #Значение глобальной переменной name Greg print $Man::name,"\n";
Также определение переменной, как local позволяет использовать это значение не только в текущем блоке, но и во всех вызванных
из данного блока подпрограммах.
Пример 6:
#!/usr/bin/perl -w
use strict;
#Даем значения глобальным переменным
our $x=10;
our $y=10;
sub Display{
print "x = $x y=$y \n";
}
sub Create{
my $x=15;
local $y=20;
print "x = $x y=$y \n";
Display();
}
Create();
Результат :
x = 15 y=20 x = 10 y=20
Отключение директивы strcit 'refs' позволет получить значение переменной, не по ссылке на неё, а лишь по имени, хранящемуся в другой переменной.
Пример 7:
#!/usr/bin/perl -w use strict; #Даем значения глобальным переменным our $x=10; our $y="x"; { #Снимаем ограничение жестких ссылок no strict 'refs'; #Выводим значение переменной х по её имени, записанному в переменную y print ${$y}, "\n"; } #Здесь можно получить значение переменной х, только через "реальную" (жесткую) ссылку $y=\$x; print ${$y}, "\n";
Аналогичным образом можно подставлять не только имена переменных, но и имена классов , пакетов и т.д.