perl - 如何在 perl 的本地范围内访问导入模块中的变量?

标签 perl moose perl-exporter

我在创建 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 .

至于你想做什么,有两个直接的问题

    来自 XYZ
  • $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。这是全局问题的一个很好的例子。一旦引入它们,我们就必须始终任何地方小心它们。

但是跨模块共享变量存在更大的问题。

它使代码组件纠缠在一起,代码变得越来越难处理。它违背了明确定义的范围和模块化设计的原则,它支持远距离操作等。Perl 提供了许多用于构建代码的好工具,我们很少需要全局变量和共享变量。这表明 Exporter 本身 warns against that .

请注意现在 XYZ 中的 my $VARXYZ 之外不可见; XYZ 之外的任何代码都无法知道或访问它。 当它是我们的 时,解释器中的任何代码可以将它简单地写成 $XYZ::VAR,甚至不需要导入它;那是我们想要的。

当然,可能需要或很好地使用导出变量,偶尔可以在模块中找到。不过,这是一个异常(exception),要谨慎谨慎地使用。


除非通过 our 将它们声明为词法别名下的包全局变量在他们的 package ,在这种情况下,它们可以作为$TheirPackageName::varname任何地方使用。

这个完整privacy is courtesy of my .

关于perl - 如何在 perl 的本地范围内访问导入模块中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41880411/

相关文章:

perl - 如何在 CGI 环境中避免 Excel::Writer::XLSX 的编码问题?

perl - 如何将 undef 作为参数从 TT 模板传递给对象方法?

perl - Moose 和约束类变量

Perl:使用 glob 对具有用户定义长度的数组中的值进行排列

perl - 如何获取整个命令行字符串?

python - 属性错误 : module 'cv2.cv2' has no attribute 'TrackerMOSSE_create'

perl - 对其他角色实现要求不起作用?

Perl Exporter 在子类中使用来自@EXPORT_OK 的变量

perl - 如何有条件地从另一个模块导入函数并将它们导出到本地命名空间