2011-06-08 80 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