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!!