Rubyリファレンスマニュアルには、『繰り返しを行うクラスのMix-in』とある。

これは、ユーザーが定義したクラスに、配列要素を対象とする様々な嬉しいメソッドを付加するモジュールなのである。

Rubyリファレンスマニュアルを見ても、もう、『こんなに追加してもらっていいんですか?ほんとに?』とお礼を言いたくなるほどに、山ほどメソッドが利用できるようになるわけだが、ここにひとつの落とし穴がある。

それは、リファレンスマニュアルにさらっと記してある、『このモジュールのメソッドは全て each を用いて定義されているので、インクルードするクラスには each が定義されていなければなりません』という一文だ。

Arrayを継承して作るようなクラスであれば別として、このEnumerableモジュールの力を借りようとすれば、内部的に配列的要素を内包し、かつ、『eachメソッド』を実装せねばならないのである。

どうやって?

『コルーチン』を使うのである。

コルーチンとは、通常のサブルーチンがエントリーからリターンまでを一つの処理単位とするのに対し、いったん処理を中断した後、続きから処理を再開できるというもので、マルチスレッドを言語レベルでサポートするものなのである。

コルーチンをサポートしている言語はまだ数が少なく、メジャーなところでは、我らがRubyとC#ぐらいのものなのだ。C#のコルーチンについては、この物語の作者の著作、『絶対現場主義-VisualC#実践講座』で解説しているので、そちらをご覧いただきたい(さりげなくコマーシャル)。

それでは実際にコードで解説してみよう。

001 | #Enumerableをテストするクラス
002 | class Enumer
003 |     include Enumerable #EnumerableのMix-in
004 |     #eachメソッド
005 |     #2,5,4,6,1,3の順でひとつずつ値を返す。
006 |     def each()
007 |         [2,5,4,6,1,3].each{|elm|
008 |             yield(elm) 
009 |         }
010 |     end
011 | end
012 | 
013 | enm=Enumer.new
014 | 
015 | p enm.sort

ここまで一緒にRubyを勉強してきた皆さんにとってこのようなコードは屁みたいなものであろうが、このコードのキモは、6行目からのeachメソッドの定義、そしてメソッドyieldである。このeachメソッドは、呼び出される都度、2,5,4,6,1,3の配列の中から順番にひとつずつ値を取り出して戻り値とするのだ。

15行目で、実際には定義した覚えのないsortメソッドが呼び出されているのがわかるだろう。これがEnumerableモジュールに定義されているメソッドというわけである。

ちなみにこのコードの実行結果は次の通りだ。

[1, 2, 3, 4, 5, 6]

まあ驚くほどのこともなく、予想通りであって、こう動いてもらわなくては困るのであるけれど。


最終更新:2009年03月10日 21:43