Локальный хэш инициализации в модуле Perl в пустой хэш


Когда я инициализирую локальный хэш (используя "my") в модуле perl, хэш кажется пустым внутри функций модуля.

Вот код модуля 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", то он отлично работает в обоих случаях.

Что я упускаю?

2 4

2 ответа:

our создает лексический псевдоним для переменной пакетас динамической областью действия , на которую может ссылаться $Fully::Qualified::name.

my создает переменнуюс лексической областью , на которую можно ссылаться только с помощью $name.

Опираясь на комментарий @Schwern , под "лексическим" мы подразумеваем ограниченный блок и любые последующие вложенные блоки, но не видимый внутри других блоков (например, в другом месте-определенная подпрограмма, вызываемая из блока, который объявляет my $lexical_var не может видеть эту переменную).

Итак, в вашем коде my %h - это переменная, лексически ограниченная неявным блоком заключающего ее файла (Test.pm our %h, с другой стороны, является лексическим псевдонимом для совершенно другой переменной, в частности для пакетной (глобальной) переменной, полное имя которой %Test::h. В обоих примерах ваш sub test запрашивает переменную пакета по ее полному имени. Но только во втором примере вы присваиваете этой переменной какие-либо значения.

(вы не спрашивали об этом специально, но local динамически определяет область действия данной переменной пакета для заключающего файла, блока или eval. Вы несколько раз используете прилагательное "local" в своем посте, что несовместимо с тем, что оно означает как ключевое слово perl.)

Ой-что ты пытаешься сделать? Есть ли причина для этого " использовать 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;