Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Ruby辞典

  1. トップページ
  2. Ruby辞典
  3. module / include / extend / mixin

module / include / extend / mixin

Rubyのモジュール(module)とミックスイン(mixin)の仕組みです。複数のクラスに共通の機能を持たせる多重継承の代替手段として使われます。

構文
# モジュールの定義。
module モジュール名
  def インスタンスメソッド
    処理
  end

  def self.モジュール関数
    処理
  end
end

# include: モジュールのメソッドをインスタンスメソッドとして追加します。
class クラス名
  include モジュール名
end

# extend: モジュールのメソッドをクラスメソッドとして追加します。
class クラス名
  extend モジュール名
end

# prepend: include より前にメソッド探索チェーンに挿入します(メソッドの前処理に使います)。
class クラス名
  prepend モジュール名
end

# 特定のオブジェクトにだけモジュールを extend します(シングルトンメソッド)。
オブジェクト.extend(モジュール名)
メソッド一覧
構文 / メソッド概要
module モジュール名モジュールを定義します。インスタンス化できず、クラスと異なり継承もできません。
include モジュール名モジュールのメソッドをクラスのインスタンスメソッドとして追加します。
extend モジュール名モジュールのメソッドをクラスのクラスメソッドとして追加します。
prepend モジュール名モジュールをメソッド探索チェーンの先頭に挿入します(オーバーライドの前処理に便利です)。
include? / ancestorsクラスがどのモジュールをインクルードしているか確認できます。
サンプルコード
# 挨拶機能を提供するモジュール。
module Greetable
  def greet
    "こんにちは!私は#{name}です。"
  end

  def farewell
    "さようなら!#{name}でした。"
  end
end

# ログ機能を提供するモジュール。
module Loggable
  def log(message)
    puts "[LOG] #{self.class}: #{message}"
  end
end

# include でインスタンスメソッドとして追加します。
class Person
  include Greetable
  include Loggable

  attr_reader :name

  def initialize(name)
    @name = name
  end
end

class Robot
  include Greetable

  attr_reader :name

  def initialize(name)
    @name = name
  end
end

# モジュールのメソッドが使えます。
p = Person.new("Alice")
puts p.greet    # こんにちは!私はAliceです。
puts p.farewell  # さようなら!Aliceでした。
p.log("起動しました")  # [LOG] Person: 起動しました

r = Robot.new("R2D2")
puts r.greet    # こんにちは!私はR2D2です。

# モジュールの確認。
puts Person.ancestors.inspect
# [Person, Loggable, Greetable, Object, Kernel, BasicObject]
概要

Rubyは多重継承を持ちませんが、モジュールのミックスインによって複数のクラスに共通機能を持たせることができます。モジュールは「機能の集まり」としてクラスとは別に定義し、必要なクラスに『include』または『extend』で取り込みます。

『include』はモジュールのメソッドをインスタンスメソッドとして追加し、『extend』はクラスメソッドとして追加します。メソッド探索の順序は『ancestors』で確認できます。後からインクルードしたモジュールが探索順で前になります(スタック構造)。

モジュールはインスタンス化できません。モジュールに状態(インスタンス変数)を持たせると、インクルード先のクラスのインスタンス変数と混在するため混乱を招きます。モジュールにはなるべくステートレスなメソッドのみを定義することが推奨されます。

標準ライブラリの『Comparable』モジュールを使ったカスタム比較については『Comparable / <=>』を、継承の仕組みは『継承 / super』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。