LoginSignup
5

More than 3 years have passed since last update.

posted at

updated at

[Ruby] モジュールの include と prepend-[1]

モジュールを include したときと prepend したときでは継承順序が異なる.
結果, 同じモジュールを include したときと prepend したときでは当然挙動が変わってくる.

確認環境

  • Ruby v2.3.7p456

モジュール定義とクラス定義

define_module_define_class.rb
# まずはモジュール定義
module M
  def hoge
    puts "hoge is defined by module"
  end
end

# 定義したモジュールを include するクラス
class ClsInludeModule
  include M
  def hoge
    super
    puts "hoge is defined by ClsIncludeModule"
  end
end

# 定義したモジュールを prepend するクラス
class ClsPrependModule
  prepend M
  def hoge
    super
    puts "hoge is defined by ClsPrependModule"
  end
end

継承関係の確認

verify_inheritane.rb
# モジュールを include したクラス
ClsInludeModule.ancestors # :=> [ClsInludeModule, M, Object, Kernel, BasicObject]

# 継承関係の確認(モジュールを prepend したクラス)
ClsPrependModule.ancestors # :=> [M, ClsPrependModule, Object, Kernel, BasicObject]

挙動の確認

verify_behavior.rb
# モジュールを include したクラス
ClsInludeModule.new.hoge # :=> hoge is defined by module
                         # :=> hoge is defined by ClsIncludeModule

# モジュールを prepend したクラス
ClsPrependModule.new.hoge # :=> hoge is defined by module

結論

  • モジュールを include した場合

    • モジュールは include を行ったクラスの 「上」に来る
    • したがって同名メソッドが定義されている場合, super で呼び出した際には モジュールのメソッドが実行される
  • モジュールを prepend した場合

    • モジュールは prepend を行ったクラスの 「下」に来る
    • この場合, prepend を行ったクラスのメソッドは prepend したモジュールのもので オーバーライド される
    • したがって prepend を行ったクラスのメソッドは実行されない

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5