モジュールとは?
クラスのようでクラスではないRuby特有の概念です。
クラスとの違い
- モジュールから、インスタンスを作成することはできない。
- 継承はできない。(他のクラスやモジュールから)
用途
- クラス名、定数名の衝突を防ぐ(.netで言うところの「名前空間」のようなもの)
- ミックスイン(継承を使わずに複数のクラスに対して、共通のクラスメソッドやインスタンスメソッドを定義できる。)
- 関数的メソッドを定義する。
- シングルトンオブジェクトのように扱って設定値を保持する。
ミックスイン
例えば、複数クラスがあったとしてどちらも「ログ出力機能」を持っていたとしたらコードが重複してしまいます。
継承を使えば共通化できそうな気はしますが、お互いに関係のないクラスの場合は安易に継承によって共通化を図るのは間違いです。また、Rubyのクラスは一つの継承元からしか継承することはできず多重継承を禁止しています。
そこで活用するのがモジュールで、クラスにモジュールをincludeして機能を追加します。それをミックスインと言います。
シングルトンオブジェクトのように扱って設定値を保持する。
クラスにも設定値を持たせることはできますが、モジュールはインスタンス化できないので他の開発者に勘違いさせるリスクを減らすことが可能です。できるだけモジュールを使って設定値を持たせるようにしましょう。
モジュールの使い方
構文
クラスの定義に似ていますよね。「module」の部分を「class」に変更すれば、クラスの構文と同じになります。
1 2 |
module モジュール名 end |
メソッド
モジュールはインスタンス化できないので必ずメソッド名の前にはselfを付けます。
1 2 |
def self.メソッド名 end |
定数の呼び出し
1 |
モジュール名::定数名 |
なお、後述するモジュールをincludeした後であれば「モジュール名::」の記述は省略することが可能です。
モジュールファンクション
下記のようにしてモジュール内のメソッドを呼び出す方法もあります。
1 2 3 4 5 6 7 8 |
module モジュール名 def モジュールファンクション名(引数) end module_function :モジュールファンクション名 end モジュール名.モジュールファンクション名(引数) |
クラスから呼び出す。(ミックスイン)
インスタンスメソッドを呼び出す場合
呼び出す側のクラス内に下記の記述をします。
1 |
include モジュール名 |
クラスメソッドを呼び出す場合
1 |
extend モジュール名 |
標準のモジュールの種類
自分でモジュールを作らなくてもすでにRuby標準で用意されていて組み込まれているモジュールがいくつかあります。
Enumerableモジュール
配列、ハッシュ等の何らかの繰り返し処理ができるオブジェクトにinculudeされているモジュールです。
このモジュールにはmapやselect等の様々な便利な集計用のメソッドが用意されていて使うことができます。
Comparableモジュール
比較演算子(<、<=、=)等は実はComparableというモジュールだったのです。
Kernelモジュール
普通に使われているputs等の構文はKernelモジュールになります。全てのクラスの基底クラスであるObjectクラスはこのモジュールをincludeしています。
Kernelモジュールで使えるメソッドの例
- puts
- p
- require
- loop
下記のドキュメントを見ればKernelモジュールを全て把握することができます。
https://docs.ruby-lang.org/ja/latest/class/Kernel.html
この記事へのコメントはありません。