2008-11-04 63 views
7

下面是一些簡單的Perl來計算數組中出現值的次數。這運行沒有任何警告。Perl何時自動初始化變量?

use warnings; 
use strict; 

my @data = qw(1 1 2 3 4 5 5 5 9); 
my %histogram; 
foreach (@data) 
{ 
    $histogram{$_}++; 
} 

當循環體改爲

$histogram{$_} = $histogram{$_} + 1; 

Perl中警告說, 「除了未初始化值的使用」。

這是怎麼回事?爲什麼當作爲操作數提供給++運算符並且未使用+運算符初始化時,初始化該值?

回答

14

+運算符評估左邊的表單和右邊的表單,然後返回兩者的總和。散列調用評估沒有看到任何特殊的上下文。

++運算符時有一些特殊的魔法建在從perlop中手冊頁引用,關於++運算符:

「民主基金」始終被視爲數字,尤其是前改變爲0遞增(這樣undef值的後增量將返回0而不是「undef」)。

編輯:要闡述的區別,++改變地方的價值,而只是+採用它的參數作爲輸入。當+看到未定義的值時,通常出現了問題,但對於++,您的散列操作示例非常典型 - 用戶希望將undef視爲0,而不必每次都檢查和初始化。因此,以這種方式對待這些運營商似乎是有道理的。

7

這不是Perl必須初始化值,但它並不總是警告他們。不要試圖爲此考慮一條規則,因爲你總是會發現異常,而當你認爲你已經發現異常時,下一個版本的Perl將改變你的警告。

在這種情況下,正如Harleqin所說,自動增量算子有一個特例。

0

正如布賴恩所說:它仍然如此,它只是警告你。警告會告訴您某些您可能無意使用的效果的操作。

您具體要求要求的值爲$histogram{$_},將值加1,然後將其分配給同一個槽。這是我不希望對自動激活這裏的工作方式相同:

my $hash_ref = $hash_for{$key_level_1}; 
$hash_ref->{$key_level_2} = $value; 

因爲它在這裏:

$hash_for{$key_level_1}{$key_level_2} = $value; 

魔術可能不會像優化工作。優化編譯器會注意到a = a + 1a++是一樣的,所以在彙編語言中有一個增量操作符時,它可以使用該優化指令而不是假裝它需要保留第一個值,然後覆蓋它,因爲它不是實際上並不需要。

爲了提高每次運行的性能,優化是額外審查和開銷一次。但是,動態語言並不能保證你不會以相同的速度增加開銷,否則你會試圖減少開銷。

+0

儘管警告不會直接破壞構建,但應該注意它們。 – Svante 2008-11-04 12:57:02

7

某些操作員故意省略「未初始化」警告,以方便您使用 ,因爲它們通常用於左側或唯一操作數的0或「」默認值有意義的情況。

它們是:++和 - (或者pre或post),+ =, - =,。=,| =,^ =,& & =,|| =。

請注意,其中一些錯誤地在使用綁定變量時發出警告:請參閱http://perl5.git.perl.org/perl.git/blob/HEAD:/t/op/assignwarn.t中標記爲TODO的測試。