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

在Perl中,如何访问另一个包中定义的标量?,perl,perl-module,Perl,Perl Module,我似乎被困在试图访问另一个包中定义的标量的过程中,并且已经将一个示例缩小为一个简单的测试用例,在这里我可以重现这个问题。 我希望能够使用我们的机制访问对包“Example”中定义的列表的引用,但是,转储程序显示Example.pl中始终未定义变量: Example.pm如下所示: #!/usr/bin/perl -w use strict; use warnings; use diagnostics; package Example; use Data::Dumper; my $expor

我似乎被困在试图访问另一个包中定义的标量的过程中,并且已经将一个示例缩小为一个简单的测试用例,在这里我可以重现这个问题。 我希望能够使用我们的机制访问对包“Example”中定义的列表的引用,但是,转储程序显示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;
在运行此代码时,第一个转储程序运行,事情看起来正常,之后,第二个转储程序example.pl运行,然后引用未定义:

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

当您使用
my
操作符时,您是在词汇上将变量名限定到您所在的范围或文件


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

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

要执行看起来像要执行的操作,必须将第一个文件中的声明更改为

our $exported_array = [ ... ];
然后,您可以在另一个文件中访问它,如

$Example::exported_array

即使
$exported\u array
示例
包中没有词汇范围,
示例
$exported\u array
和main的
$exported\u array
是两件不同的事情。更改您给出的示例的最简单方法是1。将
示例
声明中的
my
更改为
our
,并显式限定变量名

our $exported_array;

...

print Dumper $Example::exported_array;
否则,您需要创建一个
示例。(或者只编写一个
Example::import
例程——但我不打算讨论这个。)

包示例;
我们的$exported_数组=。。。;
我们的@EXPORT_OK=qw;
使用父qw;
在剧本中:

use Example qw<$exported_array>;
使用示例qw;
但是,由于您可以实际导出数组(而不仅仅是引用),因此我将:

our @exported_array = (...);
our @EXPORT_OK      = qw<@exported_array>;
...
use Example qw<@exported_array>;
...
print Dumper( \@exported_array );
our@exported_数组=(…);
我们的@EXPORT_OK=qw;
...
使用示例qw;
...
打印转储程序(\@exported\u数组);

对于较小的项目来说,使用Exporter是很好的,但是如果您有大量的代码处理模块内部的数据,则可能会。。。凌乱的对于这种类型的东西,面向对象要友好得多

为什么不构造一个方法来获取这些数据呢?事实上,为什么不用驼鹿呢

在您的Example.pm中,只需加载Moose即可-这将免费为您提供构造函数和析构函数,以及一个子例程来获取值并在默认情况下启用strict等。数组引用的声明必须稍有不同,这是因为Class:MOP(Moose鹿角下的引擎)是如何初始化属性的——您必须将其包装在代码引用(aka sub{})中。您还可以在调用包的脚本中使用Data::Dumper,而不是包本身

下午四时正

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

非常好,但它确实是为那些已经熟悉OOP的人编写的

#!/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);