Как заменить имя пакета на переменную при использовании ограничений - PullRequest
1 голос
/ 02 сентября 2011

У меня есть два пакета Perl: pack_hash и pack_run

package pack_hash;

$VERSION    = '1.00';
@ISA        = qw( Exporter );
@EXPORT_OK  = qw( %hashInfo );

$hashInfo{abc} = ['a', 'b', 'c'];

1;

package pack_run;

use stricts;
use warnings;
use Data::Dumper;
use  pack_hash qw( %hashInfo );

somethingDoing();

sub somethingDoing {
    my $var1 = \%pack_hash::hashInfo;   # getting the hash reference
    print Dumper($var1);
    ...
    ...
}

1;

Может кто-нибудь сообщить мне, возможно ли заменить имя хеш-пакета ( pack_hash ), используя любую переменную, например:

my $pakVar = "pack_hash";
my $var1 = \%$pakVar::hashInfo; 

Я знаю, что это НЕПРАВИЛЬНО / NOT_CORRECT, но я хочу этот символьный преобразователь ссылок , когда я использую ограничения. Я также хотел знать, возможно ли это сделать с eval . Но я хочу финальную переменную, здесь $ var1, которая будет ссылаться на конкретный хеш ( hashInfo );

Ответы [ 2 ]

3 голосов
/ 02 сентября 2011

Нет, это невозможно. Но это:

use strict;
use warnings;
use Symbol qw<qualify_to_ref>;

my $pakVar = 'pack_hash';
my $var1   = *{ qualify_to_ref( 'hashInfo', $pakVar ) }{HASH};

qualify_to_ref берет имя переменной пакета и имя пакета и возвращает указатель ссылки GLOB , затем вы просто получаете доступ к слоту HASH GLOB. Вы также можете сделать это следующим образом:

my $var1 = \%{ qualify_to_ref( 'hashInfo', $pakVar ) };

Но так же легко отключить strict в очень узком do;

my $var1
    = do {
        no strict;
        \%{ $pakVar . '::hashInfo' };
   };

Я понимаю, что некоторые культуры кодирования считают отключение strict или warnings "обманом". Я знаю, что у меня были вопросы о проверке кода на отключение одного класса предупреждений в таком маленьком блоке, как этот. Я знал, какие предупреждения я собирался получить, поэтому мне это не нужно. Рецензент не видел это таким образом.

По этой причине некоторые опытные сотрудники ничего не думают о строгом отключении. Но если вы не можете, потому что это делает местных жителей беспокойными - вы можете использовать Symbol. Однако в некоторых магазинах действуют правила против переменных пакета, поэтому это никогда не становится проблемой.

2 голосов
/ 02 сентября 2011

Если у вас есть метод класса, который возвращает ссылку на хеш:

package pack_hash;
use strict;
use warnings;
our %hashInfo;
$hashInfo{abc} = ['a', 'b', 'c'];
sub hashInfo { \%hashInfo }

тогда вы можете легко получить ссылку:

use strict;
use warnings;
my $pakVar = 'pack_hash';
my $hashInfo = $pakVar->hashInfo();
print @{ $hashInfo->{'abc'} };
...