Я пытаюсь написать Perl-скрипт, который вызывает функцию, написанную где-то еще (кем-то еще), которая манипулирует некоторыми переменными в области видимости моего скрипта. Допустим, сценарий main.pl
и функция есть в funcs.pm
. Мой main.pl
выглядит так:
use warnings;
use strict;
package plshelp;
use funcs;
my $var = 3;
print "$var\n"; # <--- prints 3
{ # New scope somehow prevents visibility of $pointer outside
local our $pointer = \$var;
change();
}
print "$var\n"; # <--- Ideally should print whatever funcs.pm wanted
По некоторым причинам использование local our $pointer;
предотвращает видимость $pointer
за пределами области видимости. Но если я просто использую our $pointer;
, переменную можно увидеть вне области видимости в main.pl
, используя $plshelp::pointer
(но не в funcs.pm
, так что в любом случае она будет бесполезна). Как примечание, может кто-нибудь объяснить это?
funcs.pm
выглядит примерно так:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} = 4;
}
Я ожидал, что это изменит значение $var
и напечатает 4
при запуске основного скрипта. Но я получаю сообщение об ошибке, сообщающее, что $pointer
не объявлено Эту ошибку можно устранить, добавив our $pointer;
вверху change
в funcs.pm
, но это создаст ненужную глобальную переменную, которая видна везде. Мы также можем устранить эту ошибку, удалив use strict;
, но это кажется плохой идеей. Мы также можем заставить его работать, используя $plshelp::pointer
в funcs.pm
, но человек, пишущий funcs.pm
, не хочет этого делать.
Есть ли хороший способ достичь этой функциональности, позволяя funcs.pm
манипулировать переменными в моей области, не объявляя глобальные переменные? В любом случае, если бы мы собирались использовать глобальные переменные, я думаю, мне вообще не нужно использовать динамическую область видимости.
Скажем так, невозможно передать аргументы функции по какой-то причине.
Обновление
Кажется, что local our
не делает ничего особенного в том, что касается предотвращения видимости. От perldoc :
Это означает, что когда действует use strict 'vars'
, our
позволяет вам использовать переменную пакета, не квалифицируя ее с именем пакета, но только в пределах лексической области нашего объявления. Это применяется немедленно - даже в пределах одного утверждения.
и
Это работает, даже если переменная пакета ранее не использовалась, так как переменные пакета возникают при первом использовании.
Таким образом, это означает, что $pointer
«существует» даже после того, как мы покинем фигурные скобки. Просто мы должны ссылаться на него, используя $plshelp::pointer
вместо $pointer
. Но поскольку мы использовали local
до инициализации $pointer
, он все еще не определен вне области действия (хотя он все еще "объявлен", что бы это ни значило). Более ясный способ написать это будет (local (our $pointer)) = \$var;
. Здесь our $pointer
"объявляет" $pointer
и возвращает также $pointer
. Теперь мы применяем local
к этому возвращаемому значению, и эта операция снова возвращает $pointer
, который мы присваиваем \$var
.
Но это все еще оставляет основной вопрос о том, существует ли хороший способ достижения требуемой функциональности, без ответа.