2013-03-15 95 views
0

出來沒有在那裏,我在我的代碼神祕鑰匙在Perl 5.14哈希表

my %stat =(); 
# read files and do some initialization 
# like $stat{$key} = {k1=>v1, k2=>v2, k3=>v3}; 
# I have located the buggy code 
# I want to do something according to c1 and c2 parsed from each line of the file 
if(!exists $stat{c1}) { # I thought I would have initialized all possible used keys here, but it is not true as seen below 
    $stat{c1} = {k1=>0, k2=>0, k3=>0}; 
} 
if($c1 == $c2) { 
    $stat{c1}{k1}++; 
} else { 
    $stat{c1}{k2}++; 
    $stat{c2}{k3}++; #Note: I forgot to check whether $stat{c2} has been initialized here! 
} 



map { 
    my $val = $stat{$_}{k1}; 
    print "$val\n";  # run time error shows "use of uninitalized $val" 
} keys %stat; 

使用哈希表我寫了一些打印語句來調試程序。我發現一些關鍵值神奇地出現在哈希表「%stat」中,儘管我從未插入它!說$ stat {510}儘管我永遠不會插入它,但它的值(在我的情況下是一個哈希表引用)沒有初始化。我必須寫一份聲明:

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat; 

刪除不需要的密鑰。

你能告訴我爲什麼一些神祕的鑰匙可以出現(鍵%stat)?

感謝, 傑夫

+0

它被稱爲 「自動激活」。 – varnie

+0

'if(c1 == c2)'?這看起來非常錯誤。錯字,應該是'$ c1'和'$ c2'? – TLP

+0

是的。感謝您的更正。 – Fashandge

回答

9

你能告訴我爲什麼一些神祕的鑰匙可以出現(鍵%stat)?

因爲你沒有以某種方式創建它們的代碼。

也許你做過$stat{510}{k1}?請記住,

$stat{510}{k1} 

是短期的

$stat{510}->{k1} 

$x->{...} 

確實

($x //= {})->{...} 

所以

$stat{510}{k1} 

確實

($stat{510} //= {})->{k1} 

注意如何分配給$stat{510}


使用mapfor循環是不可取的。

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat; 

更好寫成

delete $stat{$_} for grep !defined($stat{$_}{k1}), keys %stat; 

甚至

delete @stat{ grep !defined($stat{$_}{k1}), keys %stat }; 
+0

@Fashandge,讓我知道如果你決定添加有問題的代碼到你的問題。我可以建議一些避免哈希元素創建的方法。 – ikegami

+0

非常感謝您的建議!事實上,我不知道如何將$ stat {510} = {k1 = 0,k2 = 0,k3 = 0}初始化爲$ stat {510} {k2}。 – Fashandge

+0

我編輯了這個問題來添加buggy代碼。如果你有興趣,請看看它,並且首先給我一個關於如何避免這種錯誤的建議,儘管看起來只是因爲我的粗心大意。 – Fashandge

2

因爲的自動激活。這意味着當你引用一個哈希條目時,它會被創建而沒有投訴。如果您當時未指定值,則會使用值undefined進行初始化。因此,在你的代碼的一部分,你必須

##read files and do some initialization 

確保你沒有讀取或寫入與關鍵510的條目。