ActiveSupportのEnumerable#group_by

ActiveSupportのEnumerable#group_byについて。

Railsレシピブックの330ページでは、

引数に渡したブロックの戻り値をキー、その戻り値の値となる要素の配列を値とする新たなハッシュを返します。

331ページのコードでは、group_byがHashを返しています。

comments_by_date = UserComment.find(:all).group_by(&:created_at)
#=> { #<Date: 2008/05/03 =>
       [#<UserComment created_at=#<Date: 2008/05/03, text="...">,

Ruby 1.8.6とRuby on Rails2.1.0で実際に試してみたところ、group_byは次のような値を返しました。

#=> [[#<Date: 2008/05/03>, [#<UserComment ...>, #<UserComment ...>]],
     [#<Date: 2008/05/04>, [#<UserComment ...>, #<UserComment ...>]]]

Hashが返ってくるはずなのに、Arrayが返ってきています。

実は、一見するとArrayのように見えますが、ActiveSupport::OrderedHashクラスのインスタンスです。
ActiveSupport::OrderedHashはArrayクラスのサブクラスで、[]メソッドを再定義しています。
そのため、Hashと同じように[]で要素にアクセスすることができます。
ActiveSupport::OrderedHashはArrayなのですが、あたかもHashのように扱うことができるのです。

コメント

  1. 見た目Arrayで操作はhashなので一見すると混乱しますよね。
    黒魔術!黒魔術!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください