Ruby 2.1.1 に含まれる Hash#reject の不具合について

Posted by sorah on 10 Mar 2014
Translated by sorah

Ruby 2.1.0 まで、Hash を継承したクラスの reject メソッドはその継承したクラスのオブジェクトを返す挙動になっていました。 しかし、Ruby 2.1.1 で意図せずその挙動が変更され、継承したクラスの場合でも必ず Hash クラスのオブジェクトが返る挙動に変更されてしまっています。

class SubHash < Hash
end

p Hash.new.reject { }.class
#=> 2.1.0: Hash, 2.1.1: Hash
p SubHash.new.reject { }.class
#=> 2.1.0: SubHash, 2.1.1: Hash

(正確にはインスタンス変数など他の属性もコピーされなくなっています。)

Ruby 2.1.0 からバージョニングポリシーを変更しているため、Ruby 2.1.1 はパッチレベルリリースにあたります。パッチレベルリリースは後方互換性を維持すべきなため、本来 Ruby 2.1.1 にこのような挙動の変更が入るべきではありません。

この意図しない挙動変更はいくつかのライブラリに影響を与えてしまう可能性があります。一つ観測されている事例は Rails の HashWithIndifferentAccessOrderedHash です: Rails issue #14188

この挙動変更は Ruby 2.1.2 で元に戻るよう修正される予定です。しかし、これは Feature #9223 で議論されていたもので、Ruby 2.2.0 で導入される予定です。 われわれはあなたのコードをこの仕様変更を想定したものに修正する事を推奨します。

また、この不具合はあるコミットのバックポート漏れで発生してしまいました。対策などを含めた詳細はこちらの記事を参照してください: http://diary.sorah.jp/2014/02/28/ruby211-hash-reject

ご不便をおかけします。

最近のニュース

Ruby 4.0.0 リリース

Ruby 4.0.0 が公開されました。 Ruby 4.0 には “Ruby Box”、”ZJIT” ほか多数の改善が含まれています。

Posted by naruse on 25 Dec 2025

サイトのアイデンティティの再設計

サイトの包括的なデザインのアップデートを発表できることを嬉しく思います。今回の更新ではTaeko Akatsukaさんにデザインを担当していただきました。

Posted by Hiroshi SHIBATA on 22 Dec 2025

Ruby 4.0.0 preview2 リリース

Ruby 4.0.0-preview2 が公開されました。Ruby 4.0では、Unicodeバージョンの17.0.0へのアップデートなど様々な改善が行われています。

Posted by naruse on 17 Nov 2025

もっと読む...