rubyにはクラスの他にモジュールと呼ばれるものがある.rubyのモ ジュールにはクラスに良く似ているが,3つの点で異なっている.
実際,モジュールのクラスModuleはクラスのクラスClassのスーパー クラスになっている.
で,モジュールの使われ方だが,大きく分けて二つある.ひとつは メソッドや定数をまとめるためである.標準ライブラリの中では例 えばMathモジュールがこの働きをしている.
ruby> Math.sqrt(2) 1.41421 ruby> Math::PI 3.14159
あ,まだ説明していなかったが,`::'というのはそのモジュールや クラスで定義されている定数を参照する演算子だ.モジュールで定 義されているメソッドや定数を利用するためには`include'を使う.
ruby> include Math Object ruby> sqrt(2) 1.41421 ruby> PI 3.14159
モジュールのもうひとつの使い方はmixinと呼ばれるものだ.こっ ちはちょっと複雑なので,少し詳しく説明しよう.
ruby以外のオブジェクト指向言語には複数のスーパークラスから継 承する機能(多重継承)を持つものもあるが,rubyは意図的にこの機 能を持っていない.その代わりモジュールを使ったmixinという方 法で同じことを実現できる.
既に説明したようにモジュールはクラスと同じような働きをするも ので,そこでの定義されたメソッドや定数は,継承こそできないも のの,includeすることによって,他のモジュールやクラスに追加 できる.つまり,あるモジュールの定義をincludeすることによっ て,そのクラスの性質を「混ぜ混む」ことができるわけだ.これを mixinと呼んでいる.
rubyの標準ライブラリの中でmixinの代表はEnumerableである.こ れのモジュールを要素を順に返す`each'というメソッド(イテレー タ)を持つクラスにmixinすると,ソートや検索などの機能を追加す ることができる.
多重継承とmixinの違いは以下の通りである.
どちらもクラスの関係の複雑さを抑える働きがある.
rubyが多重継承を持っていない理由は,それが複雑さの原因になる からだ.クラスが複数のスーパークラスを持ち,関係のネットワー クを形成する状況は,大体において人間の頭には複雑すぎることが 多い.少なくとも僕の頭にとっては.
その点,mixinならもとのクラスに「付加したい特定の性質をまと めたもの」としてすっきりとまとめることができる.
だから,多重継承のある言語でも実際はmixin的な形で,抽象的な 性質だけまとめたクラスを多重継承して,使うのが賢いやり方だと いわれている.rubyはそれをもう一歩進めて,多重継承を無くして, mixinだけを許すようにしているわけだ.