Являются ли наши переменные динамическими? - PullRequest
7 голосов
/ 03 апреля 2019

Этот код выведет «Duo», даже если $ var не является динамической переменной с * twigil:

our $var="Duo";
sub sub1() {
    say $*var;
}

sub1();
#output is 'Duo'

Добавление unit package ABC; в начале дает ошибку времени компиляции "Динамическая переменная $ * var not found ":

unit package ABC;

our $var="Duo";
sub sub1() {
    say $*var;
}

sub1();
# compile time error

Добавление * twigil в этом случае делает переменную доступной.

Почему разница?

Редактировать1:

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

Переменные, которые предназначены для динамического использования, которые должны быть объявлены как таковые (как и все примеры, которые я могу найти).Если да, то как our позволяет работать выше?Я в замешательстве.

Редактировать 2:

Я думаю, что следующее показывает, почему я в замешательстве:

our $var="non dynamic";   #1
{say $*var;}

our $*var="dynamic";      #2
{say $*var;}


#With #2 commented output is
#non dynamic
#non dynamic
#
#With #2 in place output becomes
#(Any)
#dynamic

В первом случае(# 2 прокомментировал) Я динамически (дважды) обращаюсь к нединамической переменной.

Во втором случае переменная our $var забивается, когда объявляется our $*var и разрешается доступ к той же динамической переменнойк двум отдельным переменным.

Ответы [ 2 ]

6 голосов
/ 04 апреля 2019

Динамический поиск переменных концептуально происходит во всех динамических областях.Динамические области: сначала PROCESS::, затем GLOBAL::, а затем любые динамические области, которые есть у программы.

Поэтому, когда вы просматриваете динамическую переменную, она сначала просматривает все динамические области с текущего момента.Когда он не найдет его там, он будет смотреть в GLOBAL::, а если не найден, в PROCESS::.

Например, если вы хотите напечатать что-то на STDOUT, он будет искать$*OUT динамическая переменная.Если вы не определили один из них в своих динамических областях, он будет использовать тот из PROCESS:::

dd PROCESS::<$OUT>;
# IO::Handle element = IO::Handle.new(path => IO::Special.new("<STDOUT>")...)
6 голосов
/ 03 апреля 2019

Похоже, что динамические переменные ищутся в GLOBAL пространстве имен . Таким образом, следующие работы:

unit package ABC;

$GLOBAL::var="Duo";
sub sub1() {
    say $*var;
}
sub1();
#output is 'Duo'

Причина, по которой ваш первый пример работает, заключается в том, что (согласно документации ):

Программа пользователя запускается в пакете GLOBAL, поэтому «наши» объявления в коде mainline перейдите в этот пакет по умолчанию.

...