Skip to content

[en,ja]Add regression-of-hash-reject-in-ruby-2-1-1 #666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions en/news/_posts/2014-02-24-ruby-2-1-1-is-released.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ and [ChangeLog](http://svn.ruby-lang.org/repos/ruby/tags/v2_1_1/ChangeLog) for d
Following the previously announced [changed versioning policy of Ruby 2.1](https://www.ruby-lang.org/en/news/2013/12/21/semantic-versioning-after-2-1-0/),
this version is simply called "2.1.1".

__Update:__ We've noticed one regression in `Hash#reject`. For more details, see: [Regression of Hash#reject in Ruby 2.1.1](https://www.ruby-lang.org/en/news/2014/03/10/regression-of-hash-reject-in-ruby-2-1-1)

## Download

* <http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.bz2>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
layout: news_post
title: "Regression of Hash#reject in Ruby 2.1.1"
author: "sorah"
translator:
date: 2014-03-10 14:00:00 +0000
lang: en
---

In Ruby 2.1.0 or earlier, the `reject` method in any class that inherits `Hash` returns an object of its own class.
But in Ruby 2.1.1, this behavior has changed accidentally to return always a plain Hash object, not of the inherited class.

{% highlight ruby %}
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
{% endhighlight %}

(To be exact, extra states such as instance variables, etc aren't copied either.)

Ruby 2.1.1 shouldn't include such behavior changes, because with the release of Ruby 2.1.0 we've [changed our versioning policy](https://www.ruby-lang.org/en/news/2013/12/21/semantic-versioning-after-2-1-0/), so Ruby 2.1.1 is a patch level release and it shouldn't break backwards compatibility.

This regression could potentially affect many libraries, one such case is Rails' `HashWithIndifferentAccess` and `OrderedHash`. They are broken: https://github.com/rails/rails/issues/14188

This behavior will be reverted to the 2.1.0 behavior in Ruby 2.1.2, but is expected to be the default behavior for Ruby 2.2.0: [Feature #9223](https://bugs.ruby-lang.org/issues/9223).
So we recommend to fix your code to in order to expect this behavior change.

This accident is caused by one missing backport commit. For more detail, see http://blog.sorah.jp/2014/03/10/hash-reject-regression-in-ruby211

Sorry for any inconvenience, and thank you for your support.
2 changes: 2 additions & 0 deletions ja/news/_posts/2014-02-24-ruby-2-1-1-is-released.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ lang: ja

なお以前お伝えしましたとおり、Ruby 2.1 では[新しいバージョン表記](https://www.ruby-lang.org/ja/news/2013/12/21/semantic-versioning-after-2-1-0/)を採用していますので、単純に「Ruby 2.1.1」というのがこのリリースの名称になります。

__追記:__ Ruby 2.1.1 において、`Hash#reject` の不具合が発見されました。詳細はこちらをご覧ください: [Ruby 2.1.1 に含まれる Hash#reject の不具合について](https://www.ruby-lang.org/ja/news/2014/03/10/regression-of-hash-reject-in-ruby-2-1-1)

## Download

* <http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.bz2>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: news_post
title: "Ruby 2.1.1 に含まれる Hash#reject の不具合について"
author: "sorah"
translator: "sorah"
date: 2014-03-10 14:00:00 +0000
lang: ja
---

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

{% highlight ruby %}
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
{% endhighlight %}

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

Ruby 2.1.0 から[バージョニングポリシーを変更している](https://www.ruby-lang.org/ja/news/2013/12/21/semantic-versioning-after-2-1-0/)ため、Ruby 2.1.1 はパッチレベルリリースにあたります。パッチレベルリリースは後方互換性を維持すべきなため、本来 Ruby 2.1.1 にこのような挙動の変更が入るべきではありません。

この意図しない挙動変更はいくつかのライブラリに影響を与えてしまう可能性があります。一つ観測されている事例は
Rails の `HashWithIndifferentAccess` と `OrderedHash` です: https://github.com/rails/rails/issues/14188

この挙動変更は Ruby 2.1.2 で元に戻るよう修正される予定です。しかし、これは [Feature #9223](https://bugs.ruby-lang.org/issues/9223) で議論されていたもので、Ruby 2.2.0 で導入される予定です。
われわれはあなたのコードをこの仕様変更を想定したものに修正する事を推奨します。

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

ご不便をおかけします。