指定したモジュールを self の継承チェインの先頭に「追加する」ことで
self の定数、メソッド、モジュール変数を「上書き」
します。継承チェイン上で、
self のモジュール/クラスよりも「手前」に追加されるため、結果として self で定義されたメソッドは override
されます。
...
継承によってこの「上書き」を処理するため、prependの引数として渡したモジュールのインスタンスメソッドでsuperを呼ぶことでself のモジュール/クラスのメソッドを呼び出す
ことができます。
superを呼ぶことでprependしたクラスのモジュール/クラスのメソッドを呼び出す
irb(main):001* module X
irb(main):002* def foo
irb(main):003* puts "X1" # (1x)
irb(main):004* super # (2x)
irb(main):005* puts "X2" # (3x)
irb(main):006* end
irb(main):007> end
irb(main):008>
irb(main):009* class A
irb(main):010* prepend X
irb(main):011*
irb(main):012* def foo
irb(main):013* puts "A" #(1a)
irb(main):014* end
irb(main):015> end
irb(main):016>
irb(main):017> A.new.foo
X1
A
X2
=> nil
最初に呼び出したのはクラスのメソッド
irb(main):001* module X
irb(main):002* def foo
irb(main):003* puts "X1" # (1x)
irb(main):004* super # (2x)
irb(main):005* puts "X2" # (3x)
irb(main):006* end
irb(main):007> end
irb(main):008>
irb(main):009* class A
irb(main):010* prepend X
irb(main):011*
irb(main):012* def hoge
irb(main):013* puts "A" #(1a)
irb(main):014* end
irb(main):015> end
irb(main):016>
irb(main):017> A.new.foo
X1
(irb):4:in `foo': super: no superclass method `foo' for #<A:0x00000001048fd130> (NoMethodError)
Did you mean? for
super
superは
現在のメソッドがオーバーライドしているメソッドを呼び出し
ます。括弧と引数が省略された場合には現在のメソッドの引数がそのまま引き渡されます。引数を渡さずにオーバーライドしたメソッドを呼び出すには super() と括弧を明示します。
irb(main):053* class Foo
irb(main):054* def foo(arg=nil)
irb(main):055* p arg
irb(main):056* end
irb(main):057> end
irb(main):058>
irb(main):059* class Bar < Foo
irb(main):060* def foo(arg)
irb(main):061* super(5) # 5 を引数にして呼び出す
irb(main):062* super(arg) # 5 を引数にして呼び出す
irb(main):063* super # 5 を引数にして呼び出す super(arg) の略記法
irb(main):064* arg = 1
irb(main):065* super # 1 を引数にして呼び出す super(arg) の略記法
irb(main):066* super() # 引数なしで呼び出す
irb(main):067* end
irb(main):068> end
irb(main):069> Bar.new.foo 5
5
5
5
1
nil
prependされたモジュールのメソッドがオーバーライドしている
irb(main):001* module A
irb(main):002* def hihi
irb(main):003* "hihi"
irb(main):004* end
irb(main):005> end
=> :hihi
irb(main):006* class B
irb(main):007* prepend A
irb(main):008* def hihi
irb(main):009* "hihi_dance"
irb(main):010* end
irb(main):011> end
=> :hihi
irb(main):012> B.new.hihi
=> "hihi"
irb(main):013> exit
irb(main):001* module A
irb(main):002* def hihi
irb(main):003* super
irb(main):004* end
irb(main):005> end
=> :hihi
irb(main):006* class B
irb(main):007* prepend A
irb(main):008* def hihi
irb(main):009* "hihi_dance"
irb(main):010* end
irb(main):011> end
=> :hihi
irb(main):012> B.new.hihi
=> "hihi_dance"