在Perl中,如何访问另一个包中定义的标量?

时间:2010-12-07 16:51:37

标签: perl perl-module

我似乎一直试图访问另一个包中定义的标量,并将示例缩小到一个简单的测试用例,我可以重现这个问题。 我希望能够使用我们的机制访问对包'示例'中定义的列表的引用,但是,Dumper显示变量在example.pl:

Example.pm如下所示:

#!/usr/bin/perl -w

use strict;
use warnings;
use diagnostics;

package Example;
use Data::Dumper;

my $exported_array = [ 'one', 'two', 'three' ];
print Dumper $exported_array;

1;

使用此包的代码如下所示:

#!/usr/bin/perl -w

use strict;
use warnings;
use diagnostics;
use Data::Dumper;

use lib '.';
use Example;

{ package Example;
  use Data::Dumper;
  our $exported_array;
  print Dumper $exported_array;
}

exit 0;

运行此代码后,第一个Dumper运行并且事情看起来正常,此后,第二个Dumper,example.pl运行,然后引用未定义:

$VAR1 = [
          'one',
          'two',
          'three'
        ];
$VAR1 = undef;

4 个答案:

答案 0 :(得分:7)

my声明不会创建包级别变量,也不会在任何名称空间的符号表中输入任何内容。

要做你想要做的事情,你必须将第一个文件中的声明改为

our $exported_array = [ ... ];

然后,您可以在另一个文件中访问它

$Example::exported_array

答案 1 :(得分:5)

即使$exported_array包中的Example没有词法范围,Example的{​​{1}}和{em>主 $exported_array是两件不同的事情。更改您给出的示例的最简单方法是1.在$exported_array声明中将my更改为our并明确限定变量名称。

Example

否则,您需要将our $exported_array; ... print Dumper $Example::exported_array; 设为Exporter。 (或者只写一个Example程序 - 但我不打算这样做。)

Example::import

在剧本中:

package Example;
our $exported_array = ...;
our @EXPORT_OK = qw<$exported_array>;
use parent qw<Exporter>;

但是,由于您实际上可以导出数组(而不仅仅是引用),我会这样做:

use Example qw<$exported_array>;

答案 2 :(得分:3)

当您使用my运算符时,您在词汇上将变量名称范围限定为您所在的范围或文件。

如果您希望某些内容作为合格的包数组可见,则需要像在驱动程序代码中一样使用our。我相信你还需要在.pm文件中声明一些特殊的导出变量,但在正面你不需要在驱动文件中声明our $exported_array;

答案 3 :(得分:1)

使用Exporter适用于较小的项目,但是如果你有很多代码处理模块内部的数据,事情可能会变得......凌乱。对于这类事物,面向对象更加友好。

为什么不构造一个获取此数据的方法?事实上,为什么不只是使用驼鹿?

在您的Example.pm中,只需加载Moose - 这将为您提供免费的构造函数和析构函数,以及默认情况下获取值打开严格等的子例程。由于Class:MOP(Moose鹿角下的引擎)初始化属性,所以必须声明数组引用略有不同 - 你必须将它包装在代码引用(aka sub {})中。您还可以在调用包的脚本中使用Data :: Dumper,而不是包本身。

Example.pm

package Example;
use Moose;

has 'exported_array' => (is => 'rw', default => sub { [ 'one', 'two', 'three' ] });
1;

然后从脚本中调用它:

example.pl

#!/usr/bin/env perl
use Modern::Perl '2013';
use lib '.';
use Example;
use Data::Dumper;

my $example = Example->new;
my $imported_array_ref = $example->exported_array;
my @imported_array = @{$imported_array_ref};
foreach my $element(@imported_array) { say $element; }
say Dumper(\@imported_array);

我在上面的example.pl脚本中明确地解释了引用...通过将它直接解引用到数组中它可以更简洁:

#!/usr/bin/env perl
use Modern::Perl '2013';
use lib '.';
use Example;
use Data::Dumper;

my $example = Example->new;
my @imported_array = @{$example->exported_array};
foreach my $element(@imported_array) { say $element; }
say Dumper(\@imported_array);

我认为很多更多的Perl程序员会接受Moose,如果有更简单的例子来展示如何完成简单的事情。

The Official Moose Manual非常好,但它是为那些已经熟悉OOP的人写的。