[ruby-list:47766] Hashイテレーション中の新規キー追加

From: masa <masap.hat@...>
Date: 2011-01-20 21:57:24 UTC
List: ruby-list #47766
畠山です。

Ruby 1.9.2 の変更についての質問です。
Ruby 1.9.2 ではハッシュのイテレーション中に自己のハッシュに新しくキーを追加できないようになっています。
(Ruby 1.9.1 ではできました)
(ちなみに Array のイテレーション中に自己の Array インスタンスへの要素追加は Ruby 1.8 でも 1.9 でも可能になっています)

たとえば、

h = {'1' => 1, '2' => 2, '3' => 3}
h.each_key do |k|
  p k
  if k == '3'
    h['4'] = 4
  end
end

のスクリプトは Ruby 1.8 および Ruby 1.9.1 では動作しますが Ruby 1.9.2 では動きません。
(ちなみにこの処理が dbi (0.4.5) でも使われており Ruby 1.9.2 で dbi 経由でデータベースにアクセスしようとするとエラーが出ました)

ruby-talk や ruby-list でもハッシュの再代入や順序に関連していくつか議論されていますが、どうして Ruby 1.9.2
からこの変更がおこなわれたのか疑問に思っています。

参考
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23614
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/43857

というのも、
Ruby 1.8 まではハッシュの順序が記憶されていなかったので、イテレーション中に自己のハッシュデータを書き換えるとその後の処理が予測できないので思わぬバグにつながりかねませんが、Ruby
1.9 からはハッシュの順序が記憶されるようになっているので、論理的には処理の予測が可能だと思うからです(Array
と同様に)。おそらく実装上の問題でこの変更が行われたのだと予想しているのですが、どうしてこのような変更になったのか(しかも1.9.0の変更ではなくて1.9.2からなのか)、理由を教えてもらえませんでしょうか。
(個人的には処理速度やプログラム開発効率うんぬんというよりも、動的な挙動が制限されてしまっていて Ruby らしさ(Ruby
の楽しさ)が一つ減ってしまった気がして残念です)

どうぞよろしくお願いします。
もしメーリングリストでの議論を見落としていましたらすいません。

畠山

In This Thread

Prev Next