モジュールはメソッドや定義などの処理をまとめることができる機能ですが、クラスとは違い
- インスタンスを作る
- クラスの継承
の上記の2点はモジュールではできません。
モジュールの作成
モジュールを定義する場合の記述方法は下記のような感じになります。
1 2 3 |
module モジュール名 処理内容 end |
それではまずモジュールを作ってみましょう。
1 2 3 4 5 6 7 8 9 10 11 |
module TestModule VERSION = 1.0 def hello puts "こんにちは" end module_function :hello end p TestModule::VERSION TestModule.hello |
1.0 こんにちは
2行目で定数を定義していますが、この定数はクラスのときと似たような感じで「モジュール名::定数」という記述を行えば、モジュールの外からでも取り出すことができます。
モジュールでは通常「モジュール名.メソッド名」といった形式での呼び出しができませんが、7行目のように「module_function :メソッド名」と入れてあげれば呼び出すことができるようになります。
また、「module_function :メソッド名」といった記述を行わなくても下記のように「self」を使ってあげればOKです。
1 2 3 4 5 6 7 |
module TestModule def self.hello # TestModule.helloでもOK puts "こんにちは" end end TestModule.hello |
こんにちは
インクルードしてみる
インクルードするとモジュールが持っているメソッドや定数などは「モジュール名.メソッド名」ではなくそのまま「メソッド名」として使うことができるようになります。
書き方は10行目のように「include モジュール」名と記述します。
1 2 3 4 5 6 7 8 9 10 11 12 |
module TestModule VERSION = 1.2 def hello puts "こんにちは" end module_function :hello end include TestModule p VERSION hello |
1.2 こんにちは
モジュールの用途とは?
モジュールには主に下記の2つの代表的な使い方があります。
- 名前空間⇒名前どうしの衝突を避ける
- Mix-in⇒モジュールの処理をクラスに入れる
名前空間
空間名前とはメソッド名、定数名、クラス名などで同じ名前が複数存在しないように区別しているもののことを言います。
time,start,checkなどの簡単で汎用性の高い名前は他の人も使っている可能性が十分あります。空間名前を使うと他人が作ったプログラム、ライブラリなどを使用する場合に同名の名前同士の衝突が起こるのを未然に防ぐことができます。
例えば下記のようなメソッドがすでにあったとします。
1 2 3 4 5 6 7 |
def input puts "input now" end def output puts "output now" end |
このようなメソッド名が定義されていた場合で、自分も同じ名前で違う処理を入れてしまうと、名前の衝突が起こってしまいます。その場合は自分で作ろうとしているメソッド名を変更する必要が出てきますが、モジュールの名前空間を利用すれば、メソッド名を変えずに名前どうしの衝突を回避することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def input puts "input now" end def output puts "output now" end module My def input puts "input now!!!" end def output puts "output now!!!" end module_function :input, :output end input output My.input My.output |
input now output now input now!!! output now!!!
これで無事メソッド名を変更せずに処理を追加することができました。
Mix-in(ミックスイン)
Rubyは単純継承なので既に、スーパークラスからサブクラスを作っていた場合には共通機能を追加することが難しくなります。そこで同一の処理を継承関係にない別々のクラスに単に機能として一気に追加するときに「Mix-in(ミックスイン)」は非常に使えます。
それではMix-in(ミックスイン)を使ってクラスにモジュールの処理を追加してみましょう。クラス定義の中でインクルード(include)するとモジュールを「Mix-in」することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
module ModuleMix def info puts self.class end end class Class1 include ModuleMix end class Class2 include ModuleMix end Class1.new.info Class2.new.info |
Class1 Class2
今回は「self.class」を使ってレシーバのクラス名を表示させる「info」メソッドをモジュール内で作ってみました。これを両方のクラスにインクルードして「info」メソッドを使ってあげればおのおのでクラス名の表示ができるようになります。
コメントを残す