我在遗留代码中重构了一个perl模块,这是模块中的一个函数:
sub get_user {
my $user = __PACKAGE__->{user};
if (!defined $user) {
# more code
__PACKAGE__->{user} = $user;
}
return $user;
}
此模块在use strict
下编译。而且没有定义包变量。
__PACKAGE__->{user}
是什么意思?
答案 0 :(得分:14)
__PACKAGE__
是当前包的名称;您的代码将其用作符号哈希引用。因此,如果您的包是foo,则设置为$foo::foo{'user'}
。这有点奇怪;我怀疑这可能是一个错误。
因为它是一个符号引用,所以不应该在严格的范围内。然而,似乎至少在当前包具有多个部分时(例如Foo :: Bar,而不仅仅是Foo)。 不过,我不会依赖这个保持有效的错误。
答案 1 :(得分:7)
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
}
--output:--
10
X::Y
包名称可以是'X :: Y',但包的符号表名为'X :: Y ::'(注意尾随冒号)。符号表是perl哈希值,%X :: Y :: hash中的键是X :: Y包中使用的全局名称。相应的值是每个名称的typeglobs:
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
say $X::Y::{user}; #Hash name is %X::Y::
}
--output:--
10
X::Y
*X::Y::user
但是op:
中的表达式__PACKAGE__->{user}
相当于:
'X::Y'->{user}
我没有看到该行如何成功地从名为'X :: Y ::'的哈希中检索任何内容(以两个冒号结尾)。事实上,我得到了这个错误:
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
say $X::Y::{user};
say __PACKAGE__->{user};
}
--output:--
10
X::Y
*X::Y::user
Use of uninitialized value in say at 2.pl line 13.
如果代码实际上在某处创建了一个名为%X :: Y的哈希,那么代码将运行而不会出错:
use strict;
use warnings;
use 5.012;
%X::Y = (); #This hash has nothing to do with the hash named
#%X::Y::, which is the symbol table for the
#X::Y package.
$X::Y{user} = 'hello';
{
package X::Y;
sub get_user {
say __PACKAGE__->{user};
}
get_user;
}
--output:--
hello
如评论中所述,%X :: Y哈希与X :: Y包无关。实际上,这一行:
%X::Y = ();
在X包中显式声明一个名为Y的变量。 X包和X :: Y包是两个不同的包。
并且没有定义包变量
子名称是包变量:
use strict;
use warnings;
use 5.012;
{
package X::Y;
sub get_user {say 'hello';}
say $X::Y::{get_user};
}
--output:--
*X::Y::get_user
名称'get_user'的typeglob存在,这意味着代码至少使用一个名为'get_user'的全局变量。
答案 2 :(得分:-5)
__PACKAGE__
是一个哈希值。此语法访问键控值。