自動的にEnumerableのメソッドとeach_*をくっつけてみる
1.9からは組み込みとなるenumratorは便利ですが、あんまり見た目はすっきりしないのでこんなの書いてみました。
require 'enumrator' module Enumerable def method_missing(meth_sym, *args, &block) tmp = meth_sym.to_s.split("_") after_meth = tmp.shift before_meth = tmp.unshift("each").join("_") if self.methods.include? before_meth and self.methods.include? after_meth enum_for(before_meth.to_sym).__send__(after_meth.to_sym, *args, &block) else raise NoMethodError end end end
これを使うとmap, select, inject, grepなどのメソッドとeach_*なメソッドを勝手にくっつけて呼び出せるようになります。例えば、mapとeach_byteであれば、map_byteのような感じで。mapはこの命名規則に比較的合ってる感じがしますがどうでしょうか?*1
"abcde".map_byte {|i| i.succ.chr }.join #=> "bcdef" "abcde".enum_for(:each_byte).map {|i| i.succ.chr}.join #普通に書くならこんな感じ #=> "bcdef"
問題がありそうな点としては、
- Enumerableのやつじゃないメソッドとeach_*をくっつけることが可能
- Enumerableのメソッドでも末尾に?がついているやつは出来なさそうだし、仮に出来てもなんか変。
- each_*のメソッドに引数を与えることが出来ない(each_sliceなど)
といった感じでしょうか。他にもたくさんありそうですがまぁネタなので(ry
*1:素直にmap_with_each_byteとかの方が汎用的な気がしてきた