【Ruby入門】モジュール(Module)の使い方まとめ【include, extend, Mixin】

Ruby では 処理をまとめる機能としてモジュール(Module)が用意されています。

ここでは Ruby でのモジュール(Module)の使い方を解説していきます。

 

モジュール(Module)の基本

モジュール(Module)を使うことで、複数のメソッドや定数を一箇所にまとめて整理しておくことができます

まとめておいたメソッドや定数は、他の場所から自由に呼び出して使うことができます。

 

モジュール(Module)を定義するには、以下のように書きます。

module モジュール名
  # ここにメソッドや定数を書く
end
メモ

モジュール名の最初の文字は大文字にする必要があります。

 

モジュール(Module)のメリット

モジュール(Module)を使うメリットとして、以下が挙げられます。

  • メソッドや定数を一箇所にまとめて整理しておくことができる。
  • クラスで読み込むこと(Mix-in)ができ、多重継承が実現できる。
  • 名前空間を分けて、メソッド名の重複を防げる。

 

モジュール(Module)の使い方

モジュール(Module)の使い方を、事例ごとに紹介していきます。

 

インスタンスメソッドとして読み込む(include の使い方)

モジュール内で定義したメソッドは、include を使って クラス内にインスタンスメソッドとして読み込むことができます。

メモ

インスタンスメソッドについて詳しくはこちら

 

以下は「User」クラスに「Greeting」モジュールを読み込む例。

プログラム
module Greeting
  def morning
    p "おはよう"
  end

  def night
    p "おやすみ"
  end
end

class User
  include Greeting
end

user = User.new
user.morning
実行結果
"おはよう"

「User」クラスの中で include Greeting のようにして、「Greeting」モジュールを読み込んでいます。

そのため user.morning のようにして、「User」クラスから作成したインスタンスから、「Greeting」モジュール内の「morning」メソッドを呼び出せることが確認できます。

 

クラスメソッドとして読み込む(extend の使い方)

モジュール内で定義したメソッドは、extend を使って クラス内にクラスメソッドとして読み込むことができます。

メモ

クラスメソッドについて詳しくはこちら

 

以下は「User」クラスに「Greeting」モジュールを読み込む例。

プログラム
module Greeting
  def morning
    p "おはよう"
  end

  def night
    p "おやすみ"
  end
end

class User
  extend Greeting
end

User.morning
実行結果
"おはよう"

「User」クラスの中で extend Greeting のようにして、「Greeting」モジュールを読み込んでいます。

そのため User.morning のようにして、「User」クラスから「Greeting」モジュール内の「morning」メソッドをクラスメソッドとして呼び出せることが確認できます。

 

定数を呼び出す

モジュール内では定数を定義することもでき、モジュール名::定数名 で値を呼び出すことができます。

 

以下は「Greeting」モジュールに定義した定数を呼び出す例。

プログラム
module Greeting
  LANGUAGE = "Japanese"
end

p Greeting::LANGUAGE
実行結果
"Japanese"

Greeting::LANGUAGE で、「Greeting」モジュールの「LANGUAGE」という名前の定数の値を呼び出せることが確認できます。

 

今度は include したモジュールの定数を呼び出す例です。

プログラム
module Greeting
  LANGUAGE = "Japanese"
end

class User
  include Greeting

  def get_language
    p LANGUAGE
  end
end

user = User.new
user.get_language
実行結果
"Japanese"

「User」クラス内では、include した「Greeting」モジュールの中にある定数が使えます。

「get_language」メソッドの中で p LANGUAGE で、定数が呼び出せていることが確認できます。

メモ

クラスの外からは User::LANGUAGE で定数を呼び出すこともできます。

 

名前空間を分ける

クラス名やメソッド名の重複によるプログラムの誤動作を避けるために、モジュールを使って名前空間を分けることができます。

モジュールに包まれたクラスを呼び出すときは、モジュール名::クラス名 で呼び出すことができます。

 

以下は「User」クラスを「Japan」モジュールに包む例。

プログラム
module Japan
  class User
    def hello
      p "こんにちは"
    end
  end
end

user = Japan::User.new
user.hello
実行結果
"こんにちは"

Japan::User.new で、「Japan」モジュールに包まれた「User」クラスのインスタンスが作成できることが確認できます。

また、「Japan」モジュールの外であれば、新たに同じ名前の「User」クラスや「hello」メソッドを作成しても競合することはありません。

 

以下のようにモジュールをモジュールで包むこともできます。

プログラム
module Japan
  module Greeting
    def hello
      p "こんにちは"
    end
  end
end

class User
  include Japan::Greeting
end

user = User.new
user.hello
実行結果
"こんにちは"

include Japan::Greeting のようにして、外側のモジュール名::内側のモジュール名 で読み込めることが確認できます。

メモ

開発に便利な機能をまとめたライブラリ(gem)は、競合を防ぐため、モジュールでひとまとめにしてあることが多いです。

 

モジュール関数として呼び出す(module_function の使い方)

モジュールの中で module_function を使ってメソッド名を指定すると、そのメソッドをモジュールの外から関数として呼び出すことができるようになります。

プログラム
module Greeting
  def hello
    p "こんにちは"
  end

  module_function :hello
end

Greeting.hello
実行結果
"こんにちは"

モジュールの中で module_function :hello のように指定しています。

そのため、モジュールの外から Greeting.hello で「hello」メソッドを呼び出せました。

 

今度は、include でモジュールを読み込んだクラスから モジュール関数を呼び出す例です。

プログラム
module Greeting
  def hello
    p "こんにちは"
  end

  module_function :hello
end

class User
  include Greeting

  def say_hello
    hello
  end
end

user = User.new
user.say_hello
実行結果
"こんにちは"

「User」クラスの中では、include Greeting で「Greeting」モジュールを読み込んでいるので、「Greeting」モジュールの中に記述したメソッドが、「User」クラス内で関数として呼び出せます。

「say_hello」メソッド内の hello で、「hello」メソッドを呼び出せることが確認できます。

 

モジュールの外からメソッドを直接呼び出す(self の使い方)

モジュール内のメソッド名の手前に self. をつけると、モジュールの外からメソッドを直接呼び出すことができます。

プログラム
module Greeting
  def self.hello
    p "こんにちは"
  end
end

Greeting.hello
実行結果
"こんにちは"

Greeting.hello のように、モジュール名.メソッド名で、モジュールの外から直接メソッドを呼び出せました。

メモ

モジュール外からメソッドを呼び出せる点は module_function でモジュール関数にした場合と同じですが、こちらはクラス内でモジュールを include して メソッドを関数のように呼び出すことはできません。

 

モジュールとクラスの違い

モジュールも、メソッドや定数をまとめることができる点はクラス同じですが、以下の内容がクラスと違います。

  • インスタンスを作ることができない。
  • 継承できない(include や extend で読み込むことはできる)。
メモ

モジュールは処理をまとめることに特化していて、外部からモジュールの機能を読み込んで使うといったように、補助的に使われることが多いです。

 

まとめ

以上、Ruby でのモジュール(Module)の使い方でした!

 

ここまでの内容をまとめておきます。

  • モジュール(Module)を使うことで、複数のメソッドや定数を一箇所にまとめて整理しておくことができる。
  • module モジュール名 〜 end のようにして、モジュールを定義する。
  • モジュール内で定義したメソッドは、include を使って クラス内にインスタンスメソッドとして読み込むことができる。
  • モジュール内で定義したメソッドは、extend を使って クラス内にクラスメソッドとして読み込むことができる。
  • モジュール内では 定数を定義することができ、モジュール名::定数名 で値を呼び出すことができる。また、モジュールを include したクラス内では 定数名 で値を呼び出すことができる。
  • クラス名やメソッド名の重複によるプログラムの誤動作を避けるために、モジュールを使って名前空間を分けることができる。
  • モジュールの中で module_function :メソッド名 のように指定すると、そのメソッドがモジュールの外から関数として呼び出すことができる。
  • モジュール内のメソッド名の手前に self. をつけると、モジュールの外からメソッドを直接呼び出すことができる。