我似乎一直试图访问另一个包中定义的标量,并将示例缩小到一个简单的测试用例,我可以重现这个问题。 我希望能够使用我们的机制访问对包'示例'中定义的列表的引用,但是,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;
答案 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的人写的。