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
Но выражение в операторе:
__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 = ();
явно объявляет переменную с именем Y в пакете X.Пакет 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
Тот факт, что typeglob для имени 'get_user' существует, означает, что в коде используется хотя бы одна глобальная переменная с именем 'get_user'.