イテレータをインデックス付きで回したい
Rubyにはいろいろなイテレータが標準で提供されています。いくつかのイテレータはインデックス付きで回すものが提供されています(Enumerable#each_with_indexとか)が、全てのイテレータで使えるわけではありません。
で、イテレータをインデックス付きで回す機能を何とか共通化できないかなと思って考えてみました。以下の例では、Enumerable#injectとString#each_byteをインデックス付きて回しています。
module Enumerable def yeild_with_index(meth, *args) index = -1 method(meth).call(*args) do |*bargs| index += 1 yield(index, *bargs) end end end module Enumerable def inject_with_index(init, &block) yeild_with_index(:inject, init, &block) end end class String def each_byte_with_index(&block) yeild_with_index(:each_byte, &block) end end ret = 'hoge'.each_byte_with_index do |index, byte| p [index, byte.chr] end p ret # => [0, "h"] # [1, "o"] # [2, "g"] # [3, "e"] # "hoge" ret = [1, 2, 3].inject_with_index(0) do |index, result, item| p [index, result, item] result + item end p ret # => [0, 0, 1] # [1, 1, 2] # [2, 3, 3] # 6
んー、Enumerable#each_with_indexの場合はブロックの引数がitem、indexの順番なのですが、上の例では逆になっています。何かいい解決法はないかな。