我在创建 perl Moose 模块时卡住了。
我有一个全局 pm 模块。
package XYZ;
require Exporter;
our @ISA = qw(Exporter); ## EDIT missed this line
our @EXPORT_OK = qw($VAR);
my $VAR1 = 1;
our $VAR = {'XYZ' => $VAR1};
1;
我想在我正在创建的 Moose
模块中获取 $VAR
package THIS;
use Moose;
use YAML::XS;
sub get_all_blocks{
my ($self) = @_;
require $self->get_pkg(); # this returns the full path+name of the above package
# i cannot use use lib+use since the get_pkg starts complaining
our $VAR;
print YAML::XS::Dump($XYZ::VAR); # this works
print YAML::XS::Dump($VAR); # this does not work
# i cannot use the scope resolution since XYZ would keep changing.
}
1;
有人可以帮我访问变量吗?
编辑:package XYZ
代码中遗漏了一行。
我无法触摸 package XYZ
,因为它已被其他人拥有/使用,我只能使用它:(
最佳答案
导出变量很容易出问题。
为什么不
package XYZ;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw(get_var);
my $VAR = '...'; # no need for "our" now
sub get_var { return $VAR }
...
1;
然后
package THIS;
use warnings;
use strict;
use XYZ qw(get_var);
my $var = get_var();
...
1;
参见 Exporter .
至于你想做什么,有两个直接的问题
-
来自
$VAR
永远不会导入到THIS
中。如果您需要来自其他包的符号,则需要导入它们。† 这些包必须首先使它们可用,因此您还需要将其添加到@EXPORT_OK
。 与上面类似,但使用$VAR
而不是get_var()
package XYZ; ... use Exporter qw(import); our @EXPORT_OK = qw($VAR); our $VAR = '...'; # need be "our" for this
与
package THIS; ... use XYZ qw($VAR); print "$VAR\n";
现在
$VAR
可以直接使用,包括被写入(除非声明常量);它可以在其他代码的脚下改变它的值,而这些代码可能永远不知道它的任何内容。另一种方法是使用
@EXPORT
,然后将这些符号引入到每个说use Package;
的程序中。我强烈建议仅在调用者需要明确列出他们想要的内容时才使用@EXPORT_OK
。这也很好地记录了正在使用的内容。即使您添加了它,
THIS
中仍然有一个同名变量,它隐藏( mask 、阴影)$XYZ::VAR
。所以删除THIS
中的our $VAR
。这是全局问题的一个很好的例子。一旦引入它们,我们就必须始终和任何地方小心它们。
XYZ
的 但是跨模块共享变量存在更大的问题。
它使代码组件纠缠在一起,代码变得越来越难处理。它违背了明确定义的范围和模块化设计的原则,它支持远距离操作等。Perl 提供了许多用于构建代码的好工具,我们很少需要全局变量和共享变量。这表明 Exporter
本身 warns against that .
请注意现在 XYZ
中的 my $VAR
在 XYZ
之外不可见; XYZ
之外的任何代码都无法知道或访问它。‡ 当它是我们的
时,解释器中的任何代码可以将它简单地写成 $XYZ::VAR
,甚至不需要导入它;那是我们不想要的。
当然,可能需要或很好地使用导出变量,偶尔可以在模块中找到。不过,这是一个异常(exception),要谨慎谨慎地使用。
† 除非通过 our 将它们声明为词法别名下的包全局变量在他们的 package ,在这种情况下,它们可以作为$TheirPackageName::varname
任何地方使用。
‡ 这个完整privacy is courtesy of my
.
关于perl - 如何在 perl 的本地范围内访问导入模块中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41880411/