2014-09-30 49 views
4

我在將項目從perl 5.8.8更新到perl 5.18.2時遇到了問題。
我已經減少了問題的followinig例如:Perl:在線程中使用eval時的空變量

use threads; 

my $key = "abcdef"; 

print "test1 key = $key.\n"; 

my $thr = threads->create(sub { 
    eval "print \"test2 key = \$key.\n\";"; 
}); 

$thr->join(); 

在perl的5.8.8,這給正確的輸出:

test1 key = abcdef. 
test2 key = abcdef. 

但用Perl 5.18.2,我有:

test1 key = abcdef. 
test2 key = . 

我試過其他perl版本,並且問題似乎與5.14.0版本一起出現。 我正在尋找解決此問題的最佳方法,以及有關perl beaviour修改的說明。

我發現了幾個備選方案,但沒有人對我來說似乎不錯:使用「我們的$鍵」,而不是「我的$鍵」

  • ;但這會使變量「更公開」
  • 添加「my $ toto = $ key;」在評估線之前(仍在使用eval線中的$ key);事實上,在eval線似乎解決問題之前,使用$ key做某些事情(打印,假裝,使用......)。但增加的行對函數沒有用處。

在eval命令中使用$ key而不是\ $ key不是我的解決方案,因爲在真正的程序中,我將處理更復雜的結構。

回答

4

該問題與線程無關。看到類似的PerlMonks線程。要創建一個閉包,編譯器需要知道一個變量將被使用。你可以只提子變量被關閉了:

my $thr = threads->create(sub { 
    $key; # Create a closure. 
    eval "print \"test2 key = \$key.\n\";"; 
}); 

要看到類似的無螺紋的情況下,只需創建一個範圍:

my $sub = do { 
    my $key = "abcdef"; 
    print "test1 key = $key.\n"; 
    sub { 
     $key; # <-- Comment this line to get no value. 
     eval "print \"test2 key = \$key.\n\";"; 
    } 
}; 

$sub->(); 
+0

感謝您的回答!你知道爲什麼它與Perl 5.8.8一起工作,而沒有提及變量嗎? – 2014-09-30 12:33:40

+1

你想知道爲什麼5.8.8捕獲的變量不需要?因爲這就是它的編碼。 – ikegami 2014-09-30 15:03:05

+0

@ikegami:聽起來很熟悉:) – choroba 2014-09-30 15:19:49

0

Perl有一個名爲eval兩種功能。

  • eval EXPR解析並執行Perl代碼。

  • eval BLOCK是一個異常陷阱。這在其他語言中通常被稱爲try

使用正確的函數將解決您的問題,因爲它不會嘗試使用不再存在的變量。