- モジュールとクラスの違い
- モジュールの使いどころ
- モジュールの定義
- モジュールを利用したメソッド定義(include,extend)
- 名前空間の作成
- 関数や定数を提供するモジュール
- 状態を保持するモジュール
モジュールとクラスの違い
- モジュールからインスタンスの作成はできない
- 他のモジュールやクラスを継承できない
モジュールの使いどころ
モジュールの用途は下記4つが紹介されていた。以下の用途を、複数使用した場合もよくあるらしい。
- 継承を使わずにクラスにインスタンスメソッドを追加する、もしくは上書きする
- 複数のクラスに対して共通の特異メソッド(クラスメソッド)を追加する
- クラス名や定数名の衝突を防ぐための名前空間を作る
- 関数的メソッドを定義する
- 状態を保持する
モジュールの定義
モジュール定義の構文は下記。
module モジュール名 # モジュール定義(メソッドや定数等) end
モジュールを利用したメソッド定義(include,extend)
『is-a』の関係が成り立っていない場合、継承は使うべきでない。そんな時に共通のメソッドを持たせたいというような時にモジュールを利用できる。モジュールでメソッドを定義する時には、include
とextend
を使用する。
インスタンスメソッドとして、モジュールをクラスに追加したい時は、include
でモジュールをクラスに追加する。この追加のことをミックスインという。
各クラスへのinclude
は、本の中の下記図がとてもイメージしやすくて理解の助けになると感じた。
クラスメソッドとしてモジュールをクラスに追加したいときは、extend
を使う。
また、include
の場合は、当該クラスから生成されるインスタンス全てに影響してしまうけど、特定のオブジェクトだけにメソッドを追加したいというような時には、extend
を使うとインスタンスに特異メソッドとして追加できる。
クラスとインスタンスに対してextend
を用いるイメージは、多分こんな感じだと思う。
名前空間の作成
モジュールを使って名前空間を設定できる。クラス名などが衝突するような時に、利用してあげると良い。
また、クラス定義やモジュール定義を保存するファイルパスは、慣習として名前空間をディレクトリ名、クラス名やモジュール名をファイル名に対応させるらしい。
関数や定数を提供するモジュール
『他のクラスに組み込まずにモジュールから直接メソッドを呼び出したい』という時には、モジュール自身に特異メソッドを定義して、モジュール名.メソッド名
とすればメソッドを呼び出すことができる。
また、ミックスインとしても利用したい時には、対象のメソッドを特異メソッドとして定義した後にmodule_function
メソッドで指定してあげれば良い。
ミックスインとしてもモジュールから直接呼び出せるメソッドのことをモジュール関数と呼ぶ。使い方例は下記。
状態を保持するモジュール
クラスインスタンス変数を使って、モジュール自身に変数を変数を保持させることができる。インスタンスを作って何かを操作するということがないのであれば、モジュールにしておいた方がよい。理由は変な勘違いを起こさせないため。具体的にどんな時かというと、外部ライブラリ(gem)だと、ライブラリを実行するための設定値をモジュール自身に持たせたりしている。 使い方例は下記。