Last active
March 26, 2018 13:54
-
-
Save klopp/45b005d0ba182d62025e045203cc990b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Чем отличаются между собой переменные, объявленные с помощью my, our,local, state? | |
# Что и почему напечатается, если в качестве XXX подставлять вышеуказанные 4 типа объявления переменных? | |
# | |
func() for 1..10; | |
sub func { | |
my $var; | |
$var++; | |
say "A=$var"; | |
} | |
# Здесь локальная переменная в своей области видимости. При каждом объявлении она создаётся заново, | |
# поэтому выведется 10 строк "A=1". | |
func() for 1..10; | |
sub func { | |
our $var; | |
$var++; | |
say "A=$var"; | |
} | |
# Здесь $var - глобальная для пакета переменная. Точнее, алиас для $Package::var. Выведуются строки | |
# от "A=1" до "A=10". При этом область видимости переменной ограничена функцией func(), поэтому если | |
# после цикла попробовать написать: | |
# | |
# say ++$var; | |
# | |
# то получим законную ошибку 'Global symbol "$var" requires explicit package name...'. А вот такая запись: | |
# | |
# say ++$main::var; | |
# | |
# выведет "11". | |
func() for 1..10; | |
sub func { | |
state $var; | |
$var++; | |
say "A=$var"; | |
} | |
# Статическая переменная. Результат тот же, что и для our. | |
func() for 1..10; | |
sub func { | |
local $var; | |
$var++; | |
say "A=$var"; | |
} | |
# Здесь создаётся локальная копия ранее объявленой переменной, обладающая всеми её свойствами (*). Поскольку | |
# до того переменной $var не существовало, получим ошибку 'Global symbol "$var" requires explicit package name...'. | |
# | |
# (*) Никогда не задумывался как именно это устроено на низком уровне. Видится примерно такая картина: переменная в | |
# данном случае - не одно значение, а стек значений. В каждый момент времени используется то, что на верхушке. | |
# Local добавляет новое значение в этот стек (копируя текущую вершину). А после выхода из области видимости | |
# верхушка выталкивается и используется предыдущее значение. | |
# | |
# А как вы объясните странные результаты выдачи в таком случае? | |
# | |
sub func { | |
my $var if 0; | |
$var++; | |
say "A=$var"; | |
} | |
# Создание локальной переменной, к которой позже идёт обращение, находится в левой части выражения, значение | |
# которого ложно. Следовательно, операция не сможет быть выполнена, и такая запись запрещена (была бы | |
# разрешена - наверное, приводила бы к UB). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment