perl 模块中的本地散列初始化导致空散列

Local hash initialization in perl module results in empty hash

当我在 perl 模块中初始化本地散列(使用 "my")时,散列在模块函数中似乎是空的。

这是 perl 模块代码:

package Test;

use 5.014002;
use strict;
use warnings;
use Exporter qw(import);

our %EXPORT_TAGS = (
    'all' => [ qw(test) ]
);

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

our $VERSION = '0.01';

my %h = ( "1" => "one" );

BEGIN
{
}

sub test
{
    my $a = shift;
    print $Test::h{$a} . "\n";
}

1;
__END__

在这里,测试看到一个空哈希。

如果我先声明散列,但在 BEGIN 中对其进行初始化,则它可以正常工作。这是修改后的代码:

package Test;

use 5.014002;
use strict;
use warnings;
use Exporter qw('import');

our %EXPORT_TAGS = (
    'all' => [ qw(test) ]
);

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

our $VERSION = '0.01';

my %h;

BEGIN
{
    %Test::h = ( "1" => "one" );
}

sub test
{
    my $a = shift;
    print $Test::h{$a} . "\n";
}

1;
__END__

此外,如果我改为使用 "our" 声明散列,那么它在两种情况下都可以正常工作。

我错过了什么?

our 动态范围的包变量 创建了一个 词法 别名,这种别名可以被 $ 引用完全::合格::名称。

my 生成了一个 词法范围的 变量,这种变量只能由 $name.

引用

根据@Schwern的评论,"lexical"的意思是仅限于封闭块和任何后续嵌套块,但在其他块中不可见块(例如,从声明 my $lexical_var 的块内调用的别处定义的子例程看不到该变量)。

因此,在您的代码中,my %h 是一个变量,其词法范围限于其封闭文件的隐式块(Test.pm?)。另一方面,our %h 是完全不同变量的词法 别名 ,特别是完全限定名称为 %Test::h 的包(全局)变量。在这两个示例中,您的 sub test 通过其完全限定名称查询包变量。但只有在第二个示例中,您才为该变量赋值。

(您没有具体询问,但是 local 动态地将给定的包变量范围限定为封闭文件、块或 eval。您在中多次使用形容词 "local"您的 post 与它作为 perl 关键字的含义不一致。)

哎呀 - 你想做什么? 这 'use 5.014002;' 有什么原因吗? 我的意思是,如果你尝试一些老派的东西,这很酷——我刚刚在这个网站上因为做老派的 perl 而受到批评。但是如果你正在学习,也许你想做新的东西?

我使用包等进行的 OO perl 如下所示。 不管怎样

package myModule;

sub new
{
   $class = shift;
   my $self = {};
   bless $self, $class;

   return $self;
}

sub someMethod
{
   my $self = shift;
   $self->{some} = "value";

   return $self;
}

1;