Perl,在另一个标量中按名称访问变量

时间:2011-06-08 21:44:47

标签: perl

我很确定这适用于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.

由于

4 个答案:

答案 0 :(得分:8)

您尝试执行的操作称为symbolic reference,语法为${$varname}(对于简单情况,仅为$$varname)。但是this is almost always a bad idea,因为它往往会产生非常难以诊断的错误。这就是use strict禁止它的原因。

您可以说no strict 'refs'允许符号引用,但您reallyreallyshouldn't

符号引用的两个主要替代方法是hasheshard 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-

它非常详细地包含警告​​,示例和备选方案。

相关问题