2010-11-25 3 views
1

別のパッケージで選択した名前の変数を設定したいと思います。どうやってこれを簡単にすることができますか?別のパッケージに変数を設定する

ような何か:あなたはそれを行うことができます

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

別のパッケージの変数を使用しています。 Perlはそれを許していますが、あなたは他のパッケージのデザインに暴力を加えています。もちろん、警告があります:変数がパッケージによってエクスポートされている(推奨されていませんが、確かに実行可能な)場合は、その変数を使用する権限があり、それ以上割り当てる必要はありません。 –

+0

@Jonathan:古いコードを更新する必要があります。これまでは、設定が必要なときに、絶対パスから 'require magic_config_file.pl;'を実行しました。適切なローカル設定ファイルを読むことができるモジュールに切り替えていますが、下位互換性のために '%main :: SOME_DB =(host => 'blah'、user => 'blah' ....' – viraptor

+1

@Jonathan Leffler:より大きな警告:もしあなたが書いていることがあれば(例えば、Data :: Dumper、Text :: Wrapなど) – ysth

答えて

1

$variable_nameが検証された、あなたができることを考える:

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

これを行うにはちょうど 'eval STRING'に頼る必要はありません。 – tchrist

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 

そしてもちろん、あなたがに割り当てることができますこれらの方法のいずれかをsayの代わりに使用してください。

+0

私の脳が常に痛むのはなぜですか? :) – tchrist

関連する問題