__PACKAGE __-> {foo}是什么意思?

时间:2010-07-07 13:33:15

标签: perl

我在遗留代码中重构了一个perl模块,这是模块中的一个函数:

sub get_user {
    my $user = __PACKAGE__->{user};
    if (!defined $user) {
       # more code
       __PACKAGE__->{user} = $user;
    }
    return $user;
}

此模块在use strict下编译。而且没有定义包变量。 __PACKAGE__->{user}是什么意思?

3 个答案:

答案 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__是一个哈希值。此语法访问键控值。