散列使用
each()
插入而不復位未定義的行爲哈希迭代後的結果,Perl解釋:0x13932010
在/srv/data203806/MUXmh-Migration/Newperl/localperl/lib/site_perl/5.18.1/x86_64-linux-thread-multi/forks.pm
線1736如何在插入警告後禁止散列?
一切都在我的代碼工作正常,但我發現這個錯誤。我怎樣才能壓制這個警告?
散列使用
each()
插入而不復位未定義的行爲哈希迭代後的結果,Perl解釋:0x13932010
在/srv/data203806/MUXmh-Migration/Newperl/localperl/lib/site_perl/5.18.1/x86_64-linux-thread-multi/forks.pm
線1736如何在插入警告後禁止散列?
一切都在我的代碼工作正常,但我發現這個錯誤。我怎樣才能壓制這個警告?
此警告說:
use strict;
use warnings;
use Data::Dumper;
my %h = (a=>1);
while (my ($k,$v) = each %h) {
$h{b} = 2;
}
print Dumper \%h;
這沉默的警告:
use strict;
use warnings;
use Data::Dumper;
my %h = (a=>1);
{
no warnings qw(internal);
while (my ($k,$v) = each %h) {
$h{b} = 2;
}
}
print Dumper \%h;
注意的警告類別的沉默被稱爲internal
。我怎麼知道這件事的?對於Perl的警告類別,我有什麼驚人的記憶嗎?不可以。所有Perl的錯誤和警告消息均已在perldiag中詳細記錄;對於每個警告,它都會提及它所屬的類別。
這就是說,這個警告告訴你一個真正的問題。你的代碼的行爲是未定義的;如果您切換到不同版本的Perl,它可能突然開始採取不同的行爲。比關閉警告更好的是修復你的代碼!
在我上面的例子中,速戰速決將通過副本%h
而非%h
本身使用each
循環。
use strict;
use warnings;
use Data::Dumper;
my %h = (a=>1);
{
my %tmp = %h;
while (my ($k,$v) = each %tmp) {
$h{b} = 2;
}
}
print Dumper \%h;
下面的技術,其現有的代碼最小的變化,避免危險動作抑制警告:
foreach my $key (keys %hash) {
my $value = $hash{$key};
# ...
}
$價值的分配,確保您無需返工下面的代碼包含塊。
請不要回答代碼 – danopz
這裏真正的問題是:會發生什麼?文件說它是未定義的。作爲一名Perl編碼人員,我可以忍受這一點。我個人並不在乎每個設置()會返回到哪個位置。有幾種可能性,但在我詳細說明之前,我應該說我使用each()是一個可憐的人類迭代器,因爲內置比每個()更好。
所以排隊是: - 從鍵/值集返回一些隨機對,然後按預期形式在那裏繼續。 (這對我來說沒問題,我沒有添加東西) - 重新開始。顯然這沒有發生,或者文件會這樣說。 (我不贊成這個動作) - each()返回(undef,undef)集合,然後按預期工作。不是我的第一選擇,但時好時好,如果它碰巧是未定義的可能性之一。 - 失去理智;我會在這裏使用一個豐富多彩的比喻,但基本上放鬆了所有的控制,而Perl自我打破。盡我所能,這不會發生。
由於其他貢獻者建議最好進行編碼,因此不會創建警告;但是我提供了一個例子(簡單的迭代器),我以較高的頻率(較高)擊中每一個,並以較低的頻率插入和移除項目。我發現Perl的行爲減去完全適合的警告消息。
在一些我需要更好的迭代器控制的情況下,我創建了一個合適的類來實現我認爲合適的行爲。
警告告訴你正在做某件你不被允許的事情。這不是一個虛假的警告;你應該解決問題而不是沉默警告。 – ikegami