あらゆるEnumerableライブラリ
Version 0.1.3
Copyright(c) 2001
岡田 潤(ゆん)
yun@nekome.net
http://www.nekome.net/ruby/
EachDelegatorとは、ブロックを引数に取る既存のメソッドにEnumerable能力を あとから追加するためのライブラリです。
rubyには、ひとつのクラスにeach_*と名前のついたメソッドがいくつかある ケースが見られます。Stringに対するeach_lineとeach_byteなどがその例です。
こうした複数のeach_*メソッドを持つクラスについて、eachに対してしか Enumerableなメソッドを適用できないのはいかにも不便です。こうしたジレ ンマを解消するためにこのライブラリが生まれました。
eachdelegator.rbをrequireすると、each_*、または*_eachと名前の ついたあらゆるメソッドが、 自動的にEnumerableなメソッドを呼び出せるようになります。
eachdelegator.rbは 本来ブロックと共に呼び出さなければいけないこれらのメソッドを、 ブロック無しで呼び出した場合にEachDelegatorオブジェクトを返すように 再定義します。
EachDelegatorは、eachメソッドを元のオブジェクトの元のメソッドに 転送するEnumerableなクラスです。 このクラスのオブジェクトに対して collect、grepなどのEnumerableモジュールの各種の 操作を実行すると、それらを元のメソッドに対して適用したのと同じ 結果が得られます。
例えばString#each_byteをindex付きで呼び出し、その結果をcollect するというような処理を、次のようなシンプルな形で記述できます。
p "hoge".each_byte.each_with_index.collect{|a, i| [ i, a ]} => [[0, 104], [1, 111], [2, 103], [3, 101]]
自動的に再定義されるのは、each_*または*_eachという名前で 定義されているメソッドのみです。 それ以外のメソッドについては手動でModule#each_delegatorを使って 、メソッドの再定義をしてやる必要があります。
例えば、 Arrayに隣あった要素のペアをiterateするall_pairメソッドを追加して、 それぞれの要素の差を配列に出力したいといった場合は、次のように 書きます。
require 'eachdelegator'class Array def all_pair for i in 0...(size - 1) yield at(i), at(i + 1) end self end
each_delegator :all_pair end
p [1, 3, 5, 7, 13].all_pair.collect{|a, b| b - a} => [ 2, 2, 2, 6]
EnumDelegatorからEachDelegatorへ改名した。
each_*だけでなく*_each名のメソッドも自動的に再定義するようにした。
require後に定義したeach_*メソッドも 自動的に捕捉して再定義するようにした。
ブロック以外の引数を取るメソッドもenum_delegatorの対象として 扱えるようにした。
ファーストリリース。