イテレータを便利にするenum_for
ruby 1.8.7 からenumerator が組み込みで使えるようになった。enum_for がデフォルトで使える。
enum_for
Enumerable に定義されているメソッドの多くはinclude 先のクラスのeach メソッドを使って実現されている。
例えばmap の実装は以下のようなイメージ。
class Array def _map result = [] each do |e| result << yield(e) end result end end [1, 2, 3]._map{|x| x*2} # => [2, 4, 6]
enum_for を使うと、内部で利用されるeach の代わりに他のメソッドを使うことができる。定番はeach_with_index とmap のコンボ。
# Array#map 内で使われるeach をeach_with_index に置き換える [:a, :b, :c].enum_for(:each_with_index).map # => [[:a, 0], [:b, 1], [:c, 2]]
イテレータはブロックを渡されないとenum_for(method) の結果を変えすので以下のに書ける。
[:a, :b, :c].each_with_index.map # => [[:a, 0], [:b, 1], [:c, 2]]
enum_for かっこいし、便利っぽいけど、まだ実際に使ったことない。いい使い道ないかな。
hash = {:a => 1, :b => 2, :c => 3} hash.each_value.inject{|sum, v| sum += v} # => 6
うーん。微妙。
なんか、内容とタイトルが矛盾してしまった。