2012-06-01 4 views

答えて

15

あなたは

for my $key (keys %$hash_ref) { 
    ... 
} 

はおおよそ

my @anon = keys %$hash_ref; 
for my $key (@anon) { 
    ... 
} 

と同じであるので、あなたも、ループを開始する前にkeysで返されるキーのリストを反復処理している、ハッシュを反復処理していませんハッシュから削除すると何も問題はありません。


eachは、ハッシュで反復処理を行います。呼び出されるたびに、eachは別の要素を返します。それでも、現在の要素deleteにはまだ安全です!

# Also safe 
while (my ($key) = each(%$hash_ref)) { 
    ... 
    delete $hash_ref->{$key}; 
    ... 
} 

それを反復処理しているときにハッシュの要素を追加または削除した場合、エントリがスキップまたは複製することができる - ようにはしません。例外:最近(各)返されたアイテムを削除することは常に安全です。

+0

"現在の実装で"という言葉は、実装が変更されているようなスペースがあるように思えますもう安全ではありません。私はそれに頼るつもりはありませんが、私は 'each()'を使用しません。foreachキーは問題ありません。 – LeoNerd

+0

@LeoNerd、古いPerl(少なくとも5.10)は、 "それは常に削除するのが安全です"と言うだけです。互換性の理由から、 'use feature'や他の同様のプラグマを導入せずにこれが変更されることはないでしょう。 –

+1

誰が "現在の実装"でそれを追加しましたか?それは本当に本当に良い理由がない限り、常にそこにいたわけではなく、今はそこにいるべきではありません。更新:もう存在しないようです。 – ysth

3

keys %hashは、反復を開始する前にリスト全体を一度提供するので安全です。 foreachは、実際のハッシュの内部で何を変更しても、この事前生成リストで作業を続けます。

あなたが完了するまでリスト全体を保持するので、それはあなたの記憶を奪う。

関連する問題