Установить переменную в другом пакете - PullRequest
1 голос
/ 25 ноября 2010

Я бы хотел установить переменную с выбранным именем в другом пакете. Как я могу сделать это легко?

Что-то вроде:

$variable_name = 'x';
$package::$variable_name = '0';
# now $package::x should be == '0'

Ответы [ 3 ]

2 голосов
/ 26 ноября 2010
use 5.010;
use strict;
use warnings;

{
    no warnings 'once';
    $A::B::C::D = 5; # a test subject
}

my $pkg = 'A::B::C';
my $var = 'D';

# tearing down the walls (no warranty for you):
    say eval '$'.$pkg."::$var"; # 5

# tearing down the walls but at least feeling bad about it:
    say ${eval '\$'.$pkg."::$var" or die $@}; # 5

# entering your house with a key (but still carrying a bomb):
    say ${eval "package $pkg; *$var" or die $@}; # 5

# using `Symbol`:    
    use Symbol 'qualify_to_ref'; 
    say $${ qualify_to_ref $pkg.'::'.$var }; # 5

# letting us know you plan mild shenanigans
# of all of the methods here, this one is best
{
    no strict 'refs';
    say ${$pkg.'::'.$var}; # 5
}

и если для вас имеет смысл следующее:

# with a recursive function:
    sub lookup {
        @_ == 2 or unshift @_, \%::;
        my ($head, $tail) = $_[1] =~ /^([^:]+:*)(.*)$/;
        length $tail
            ? lookup($_[0]{$head}, $tail)
            : $_[0]{$head}
    }
    say ${ lookup $pkg.'::'.$var }; # 5

# as a reduction of the symbol table:
    use List::Util 'reduce';
    our ($a, $b);

    say ${+ reduce {$$a{$b}} \%::, split /(?<=::)/ => $pkg.'::'.$var }; # 5

И, конечно, вы можете назначить любой из этих методов вместо say их.

2 голосов
/ 25 ноября 2010

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

    package Test;

    package main;

    use strict;

    my $var_name = 'test';
    my $package = 'Test';

    no strict 'refs';
    ${"${package}::$var_name"} = 1;

print $Test::test;

Так что я бы не рекомендовал это. Лучше использовать хеш.

1 голос
/ 25 ноября 2010

Учитывая, что $variable_name был проверен, вы можете сделать:

eval "\$package::$variable_name = '0'";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...