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;
当我在 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;