2010-11-25 104 views
1

我想在另一个包中设置一个带有选定名称的变量。我怎样才能轻松做到这一点?在另一个包中设置变量

喜欢的东西:

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

这是不礼貌的修补与另一个软件包变量。 Perl允许它,但是你对另一个包的设计做了暴力。当然,有一点需要注意:如果变量是由包导出的(不推荐,但肯定是可行的),那么您可能有权使用它,然后您不必做任何事情而不是分配给它。 – 2010-11-25 16:42:47

+0

@Jonathan:我需要更新一些旧代码。之前,它需要magic_config_file.pl;(来自绝对路径),当它需要它的配置时。我将它切换到一个可以读取适当本地配置文件的模块,但为了向后兼容,我需要设置`%main :: SOME_DB =(host =>'blah',user =>'blah'....` – viraptor 2010-11-25 17:09:41

+1

@Jonathan Leffler:一个更大的警告:如果它记录你可能(例如Data :: Dumper,Text :: Wrap等) – ysth 2010-11-25 17:12:05

回答

1

鉴于$variable_name进行了验证,你可以这样做:

eval "\$package::$variable_name = '0'"; 
2

你可以做到这一点,但你必须禁用像这样狭窄:

package Test; 

    package main; 

    use strict; 

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

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

print $Test::test; 

所以我不建议。最好使用散列。

1
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 [email protected]}; # 5 

# entering your house with a key (but still carrying a bomb): 
    say ${eval "package $pkg; *$var" or die [email protected]}; # 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 

当然,你可以分配到这些方法中的任何一种而不是它们。