2011-06-08 50 views
3

我很确定这可以与Perl一起工作,但我不知道如何对其进行编码。 我可以想象它与eval,但那不是我在找。Perl,按其他标量名称访问变量

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

为什么不是其他标量首先存储在哈希中? – Quentin 2011-06-08 21:49:57

+2

您正在寻找[符号参考](http://perldoc.perl.org/perlref.html#Not-so-symbolic-references) – Mat 2011-06-08 21:53:29

回答

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

$$varname = 1你想要做什么,但是当use strict;生效,这是禁止的,因此它被认为是不好的风格。

+0

嗨 我有这个想法,但严格使用我得到一个问题标量refence,没有它是行不通的。 my $ vn =“foo”; my $ foo = 2; $$ vn = 33; print $ foo; //打印出2而不是33,??? – chris01 2011-06-08 21:53:39

+0

Err,$$ varname是一个标量ref的deref,$ varname被设置为标量,而不是标量 – mrk 2011-06-08 21:54:18

+0

的引用,所以我该怎么做我在我的入门文章中描述过的(没有eval)= – chris01 2011-06-08 21:57:45

8

你正在试图做所谓的symbolic reference,而且语法是${$varname}(或只是$$varname简单的情况下)。但是this is almost always a bad idea,因为它往往会产生非常难以诊断错误。这就是为什么它被use strict所禁止。

你可以说no strict 'refs'允许符号引用,但你really,really,shouldn't

符号参考的两个主要替代品是hasheshard references。很难说哪一个更适合你的情况,因为你没有真正解释你想做什么。

+1

相反,使用哈希! – 2011-06-08 22:13:49