From: Yusuke ENDOH Date: 2011-01-21T21:25:15+09:00 Subject: [ruby-list:47774] Re: Hashイテレーション中の新規キー追加 遠藤です。 2011年1月21日19:05 masa : > But I agree with Run Paint Run Run's opinion. It may lead to > difficult bug to indeterminately fail to add a new key. > > この意見だと思うのですが、この indeterminately (不確定性) は順序が保存される場合と保存されない場合で意味が変わってきます。 そういう問題ではないのです。 以下のプログラムは畠山さんの元の例のハッシュサイズを変えただけですが、 1.8.7 で実行すると例外が出ると思います。 h = {} (1..66).each {|n| h[n.to_s] = n } h.each_key do |k| p k if k == '66' h['67'] = 67 end end このように、「1.8 では新規キー追加できていた」というのは勘違いです。 どういうサイズのときに失敗するかというと、rehash の閾値に依存するため 予測不能です。 こういう風に不確定的に失敗する挙動は、再現性の低い面倒なバグに繋がり ます (おそらく dbi というライブラリも、発症していないだけでこのバグを 持ってるのではないかと思います) 。それよりは確定的に失敗した方がマシ だろう、と言う事で trunk を変更しました。不確定的に失敗していたものが 確定的に失敗するようになっても、互換性に問題はありません。 # ちなみに 1.9.1 では失敗する例を作れませんが、これは r26672 がバック # ポート漏れしているためなので、もっとまずいです。 > 将来的にはこの禁止が解除されることを願っています。 確定的に失敗させるようにしたのはそれが簡単だったからですが、ちゃんと (常に新規キーが追加できるように) 直せるならそれもいいかも知れません。 # ただハッシュの順序が入ったときに、ハッシュのこの辺りはひどくごちゃ # ごちゃしてしまっていて、ちょっと整理してからの方がいい気もします。 -- Yusuke Endoh