我想在另一个包中设置一个带有选定名称的变量。我怎样才能轻松做到这一点?在另一个包中设置变量
喜欢的东西:
$variable_name = 'x';
$package::$variable_name = '0';
# now $package::x should be == '0'
我想在另一个包中设置一个带有选定名称的变量。我怎样才能轻松做到这一点?在另一个包中设置变量
喜欢的东西:
$variable_name = 'x';
$package::$variable_name = '0';
# now $package::x should be == '0'
鉴于$variable_name
进行了验证,你可以这样做:
eval "\$package::$variable_name = '0'";
你可以做到这一点,但你必须禁用像这样狭窄:
package Test;
package main;
use strict;
my $var_name = 'test';
my $package = 'Test';
no strict 'refs';
${"${package}::$var_name"} = 1;
print $Test::test;
所以我不建议。最好使用散列。
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
当然,你可以分配到这些方法中的任何一种而不是它们。
这是不礼貌的修补与另一个软件包变量。 Perl允许它,但是你对另一个包的设计做了暴力。当然,有一点需要注意:如果变量是由包导出的(不推荐,但肯定是可行的),那么您可能有权使用它,然后您不必做任何事情而不是分配给它。 – 2010-11-25 16:42:47
@Jonathan:我需要更新一些旧代码。之前,它需要magic_config_file.pl;(来自绝对路径),当它需要它的配置时。我将它切换到一个可以读取适当本地配置文件的模块,但为了向后兼容,我需要设置`%main :: SOME_DB =(host =>'blah',user =>'blah'....` – viraptor 2010-11-25 17:09:41
@Jonathan Leffler:一个更大的警告:如果它记录你可能(例如Data :: Dumper,Text :: Wrap等) – ysth 2010-11-25 17:12:05