Moduleについて
モジュールとは
モジュールとは、クラスと同じような構成を持っており、クラスと同じくメソッドを定義することができます。クラス内でモジュールを読み込む事で、モジュールで定義されているメソッドが使えるようになります。
Rubyの場合、クラスの継承は単一継承のみですが、モジュールであれば多数組み込むことが可能です。
クラスとの違い
・モジュールからはインスタンスを生成することはできません。
・他のモジュールやクラスを継承して新しいモジュールを作ることはできません。
モジュールの定義方法
モジュールの基本の形は以下のようになります。
module モジュール名
関数などの処理
end
モジュールはクラスと同じようにメソッドを定義することができます。クラス変数に相当するものはモジュールにはありませんが、定数は定義することができます。
また、モジュール名は必ず大文字の英語で始めます。
モジュールの使い方
クラスにモジュールをincludeやextendすることで、クラスの肥大化を防いだり、クラスをまたがった同じ処理を切り出し同じ処理の繰り返しを防ぐことができます。クラスにモジュールをincludeやextendする事をMix-inと言います。
また、クラス名や定数名の衝突を防ぐためにモジュールを使って名前空間を作ることができます。
・include
継承を使わずにクラスにインスタンスメソッドを追加したり上書きできます。
モジュールのインスタンスメソッドがincludeしたクラスのインスタンスメソッドとして使えるようになります。
module Module1 #モジュールの定義
def hello
puts "hello"
end
end
class Class1 #クラスを定義してモジュールをincludeする
include Module1
def hello
puts "hi"
super #superメソッドはオーバーライドされたメソッドを呼び出す
end
end
Class1.new.hello #クラスのインスタンスを生成してhelloメソッドを呼ぶ
=> hi
=> hello
iincludeでは、Module内で定義された特異メソッドは継承されません。
module Module2
def self.hello
puts "hello"
end
end
class Class2
include Module2
end
Module2.hello
=> hello
Class2.hello
=> NoMethodError
・extend
複数のクラスに対して共通の特異メソッドを追加できます。
モジュールのインスタンスメソッドがselfの特異メソッドとして追加されます。
module Module3
def hello
puts "hello"
end
class Class3
extend Module3
def hello
puts "hi"
end
end
Class3.hello #extendで読み込んだモジュールのインスタンスメソッドはクラスメソッドとなる
=> hello
Class3.new.hello
=> hi
しかし、クラスにモジュールで定義されたメソッドと同名のクラスメソッドを定義するとオーバーライドされます。
module Module4
def hello
put "hello"
end
class Class4
extend Module4
def self.hello
puts "hi
end
end
Class4.hello
=>hi
・名前空間の作成
クラス名や定数名の衝突を防ぐためにモジュールを使って名前空間を作ることができます。
大規模なプログラムや外部に公開するライブラリを作ったりするときはクラス名の重複が問題になることがあります。その際以下のようにモジュールを設定することで、クラス名の衝突を防ぐことができます。
モジュールに属するクラスを参照する際には、"モジュール名::クラス名" のように書きます。
class User
def say
puts "Hello"
end
end
module Person
class User
def say
puts "Wooo!!"
end
end
end
User.new.say
=> Hello
Person::User.new.say
=> Wooo!!