2014-10-31 75 views
-3

在下面的代碼塊我得到這個錯誤爲什麼變量不可用?

Variable "$host" is not available at /comp/xx.pm line 404. 

其中線404是代碼塊中的最後一行。

問題

我猜測它是Capture模塊被搞亂了if (defined $host) { ...,但我該如何解決此問題?

use Capture::Tiny 'capture'; 

my $host = $::c{slaves}{$id} if (defined $id); 

my ($stdout, $stderr, $exit) = capture { 
    if (defined $host) { 
     print "---delete $snap on host\n"; 
    } else { 
     print "----delete $snap on master\n"; 
    } 
}; # line 404 

更新

如果我評論線capture和右括號,然後執行預期print線。

+0

我可以在沒有錯誤的情況下運行代碼。 – choroba 2014-10-31 14:09:48

+0

雖然當然可能,但在建議外部框架搞砸之前,我總是確保非常確定。尤其是那些已經存在了一段時間的人。雖然你的問題是好的,否則可能會對未來的讀者有所幫助,但我會認爲這是建議是負責downvotes。 – DeVadder 2014-10-31 14:20:33

+0

您顯示的代碼全部在子程序中,對嗎? – ysth 2014-10-31 15:58:48

回答

6

的問題是這一行:

my $host = $::c{slaves}{$id} if (defined $id); 

使用my $x = value if condition目前尚未在Perl支持。它有些作品,但有奇怪的角落案件。這是一。

拆分從變量的聲明分配:

my $host; 
$host = $::c{slaves}{$id} if (defined $id); 

您可以在the documentation for the related warning讀一些更多的細節。

+3

'my $ host = defined $ id? $ :: c {slaves} {$ id}:undef;'如果你在兩條線上有嚴重的過敏症,也可以使用。 – hobbs 2014-10-31 15:34:52

+1

此問題不會導致不可用的警告。 – ysth 2014-10-31 15:57:41

+1

@ysth,這就是爲什麼我把它稱爲相關的警告,而不是「你應該看到的警告」。 – cjm 2014-10-31 16:05:14

4

的說明,請參見perldiag

Variable "%s" is not available (W closure) 

在編譯過程中,內部命名子或EVAL試圖捕捉外部詞彙不是 當前可用。這可能由於以下兩個原因之一而發生。首先,外部詞彙可以在外部尚未創建的匿名子程序中聲明。 (請記住,命名潛艇是在編譯時創建的,而匿名的潛艇是在運行時創建 。)例如,

  sub { my $a; sub f { $a } } 

在f是創建的時候,就無法捕捉到的當前值$ a,因爲尚未創建匿名子例程 。相反,由於匿名子程序已經被創造出來,是活的下面也不會發出警告:

  sub { my $a; eval 'sub f { $a }' }->(); 

第二種情況是由一個eval訪問已超出範圍的變量引起的,例如,

  sub f { 
       my $a; 
       sub { eval '$a' } 
      } 
      f()->(); 

這裏,在使用eval「$ A」被編譯時,f()是不是當前正在執行的,所以它的$一不可用於捕獲。

+0

非常有趣。這如何轉化爲我的例子?它確實是「俘獲」了嗎? – 2014-10-31 14:18:31

+0

@ialarmedalien我現在已經更新了OP,因爲如果我評論'capture'行,問題就會消失。 – 2014-10-31 14:35:41