モジュール内でsuperが書かれている時にエラーが出たり出なかったりするので試してみた。
①モジュール内のメソッドにsuperが書かれていないケース。
クラスAのfooメソッド内のsuperで、includeしているモジュールの同名メソッドが呼ばれてる。
module M
def foo
puts "モジュールM#foo"
end
end
class A
include M
def foo
super
puts "クラスA#foo"
end
end
p A.ancestors
A.new.foo
結果
[A, M, Object, Kernel, BasicObject]
モジュールM#foo
クラスA#foo
②モジュール内のメソッドにsuperを書いたケース。(エラー発生)
①と違いは、モジュールMのfooメソッドにsuperが書かれてるとこ。
クラスAインスタンスの継承関係でモジュールMのsuperclassが存在しないのでエラーが出てるみたい。
module M
def foo
super
puts "モジュールM#foo"
end
end
class A
include M
def foo
super
puts "クラスA#foo"
end
end
p A.ancestors
A.new.foo
結果
[A, M, Object, Kernel, BasicObject]
sample_module_super.rb:3:in `foo': super: no superclass method `foo' for #<A:0x007fd9921fd790> (NoMethodError)
from sample_module_super.rb:11:in `foo'
from sample_module_super.rb:17:in `<main>'
③ モジュール内のメソッドにsuperを書いて、別途クラスを追加したケース。
②との違いはクラスBを定義して、クラスAにクラスBを継承させた。
クラスAインスタンスについての継承関係だと、モジュールBのsuperがクラスBになっている。
class B
def foo
puts "クラスB#foo"
end
end
module M
def foo
super
puts "モジュールM#foo"
end
end
class A < B
include M
def foo
super
puts "クラスA#foo"
end
end
p A.ancestors
A.new.foo
結果
[A, M, B, Object, Kernel, BasicObject]
クラスB#foo
モジュールM#foo
クラスA#foo
④ 別途クラスを追加して、モジュール内のメソッドのsuperは消したケース。
③と違いは、モジュールMのfooメソッドのsuperを消したとこ。
class B
def foo
puts "クラスB#foo"
end
end
module M
def foo
puts "モジュールM#foo"
end
end
class A < B
include M
def foo
super
puts "クラスA#foo"
end
end
p A.ancestors
A.new.foo
結果
[A, M, B, Object, Kernel, BasicObject]
モジュールM#foo
クラスA#foo
感想
モジュール内のメソッドにsuperを書くとエラーが出る可能性があるのでよろしくない気がする。
参考サイト
[Ruby]やったーRuby技術者認定Gold受かったよー\(^o^)/
http://d.hatena.ne.jp/rightgo09_ruby/20121226/p1
「superはincludeされてるモジュールは呼ばれる?」
superclassでは出てこないから、呼ばれないと思ってたけど…。
module M
def hoge
puts "module M"
super
end
end
class Hoge
def hoge
puts "class Hoge"
end
end
class Fuga < Hoge
include M
def hoge
puts "class Fuga"
super
end
end
Fuga.new.hoge
結果
class Fuga
module M
class Hoge
げげ呼ばれた…。モジュールもsuperの対象になるのか…。この辺で3問くらいミスった気がするな。