我很确定这适用于perl,但我不知道如何编码。 我可以用eval想象它,但那不是我想要的。
my $foo = 0;
my $varname = "foo";
$($varname) = 1; # how to do this?
# I want to access a scalar that name is in a other scalar
# so $foo should be 1 now.
由于
答案 0 :(得分:8)
您尝试执行的操作称为symbolic reference,语法为${$varname}
(对于简单情况,仅为$$varname
)。但是this is almost always a bad idea,因为它往往会产生非常难以诊断的错误。这就是use strict
禁止它的原因。
您可以说no strict 'refs'
允许符号引用,但您really,really,shouldn't。
符号引用的两个主要替代方法是hashes和hard references。很难说哪一个更适合你的情况,因为你还没有真正解释你想要做什么。
答案 1 :(得分:3)
$$varname = 1
可以做你想要的,但是当use strict;
生效时,这是禁止的,因此它被认为是不好的风格。
答案 2 :(得分:1)
Perl有两个独立但基本兼容的变量系统。
包变量,它们是完全限定名$Some::Package::variable
或用our
声明的词汇名称。包变量存在于符号表中,对整个程序是全局的,可以是符号解引用的目标,并且可以赋予local
的动态范围。
用my
声明的词汇变量构成另一个变量系统。这些变量不存在于包或符号表中(而是存在于附加到范围的词法填充中)。这些变量不是全局变量,不能象征性地引用,也不能具有动态范围。这就是为什么你不能使用$$varname
并期望它找到一个词法变量。
您有几种方法可以解决此问题:
使用包变量,完全限定名,或使用our
声明,严格禁用,并使用符号引用:
our $x = 1;
our $y = 'x';
say $x; # 1
$$y = 5; # this line is an error if `use strict` is loaded
say $x; # 5
使用包变量并遍历符号表:
$main::x = 1;
my $y = 'x';
${$main::{$y}} = 5; # ok with `use strict`
say $main::x; # 5
最佳实践方法是使用哈希(这是上面两个例子在幕后做的,因为符号表本身就是哈希)
my %data = (x => 1);
my $y = 'x';
$data{$y} = 5;
say $data{x}; # 5
符号引用的危险在于,将程序转换为意大利面条代码或覆盖您不想要的变量通常太容易了。通过使用显式哈希,可以将您正在进行的操作限制在一个定义明确且范围有限的范围内。散列本身可以是词法,允许对变量进行适当的自动垃圾收集。
答案 3 :(得分:0)
Perl常见问题解答回答了具体的原始问题:
http://learn.perl.org/faq/perlfaq7.html#How-can-I-use-a-variable-as-a-variable-name-
它非常详细地包含警告,示例和备选方案。