LoginSignup
1
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-07-22

"前のエントリ" で モジュールを prepend すると, オーバーライドがおきると書いた.
ではモジュールを prepend したとき, オーバーライドしたメソッドのなかで super を実行するとどうなるか.

確認環境

  • Ruby v2.3.7p456

prepend 時の super の挙動

when_prepend_behavior_of_prepend.rb
# モジュールのメソッドで super を実行する
module M
  def hoge
    puts "hoge is defined by module"
    super
  end
end

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

挙動の確認

verify_behavior1.rb
ClsPrependModule.new.hoge # :=> hoge is defined by module
                          # :=> hoge is defined by ClsPrependModule

結論

prepend されたモジュールの, オーバーライドすることになるメソッドで super を実行すると, オーバーライドされる側のメソッド, つまり prepend したクラスの同名メソッドが実行されることがわかった.

おまけ

じゃあ, super で実行されるメソッド(つまり prepend したクラスのメソッド)で, さらに super を実行するとどうなるか.

verify_exec_super_in_prepended_class.rb
# モジュールのメソッドで super を実行する
module M
  def hoge
    puts "hoge is defined by module"
    super
  end
end

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

挙動の確認

verify_behavior2.rb
# 実行
ClsPrependModule.new.hoge

# 結果
hoge is defined by module
hoge is defined by ClsPrependModule
NoMethodError: super: no superclass method `hoge' for #<ClsPrependModule:0x00007fb0a3a8ee58>
    from (irb):15:in `hoge'
    from (irb):8:in `hoge'
    from (irb):18
    from /usr/bin/irb:11:in `<main>'
  1. モジュールのメソッドがコールされ実行される
  2. super で prepend したクラスのメソッドがコールされ実行される
  3. prepend したクラスの上位クラス(ここでは Objectクラス)では「hoge()メソッド」が定義されていないので NoMethodError が発生した
1
0
0

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
  3. You can use dark theme
What you can do with signing up
1
0