親の親のメソッドを実行する(RGSS・RGSS2共通というかruby)

親の親のメソッドを実行したいが親クラスでオーバーライドされてしまっている時、 気合で親の親のメソッドを呼ぶ方法。

例)
class Foo
  def initialize
    @name = "foo"
  end
  def hello
    p "Hello:#{@name}"}
  end
end

# Fooの子
class Bar < Foo
  def initialize
    @name = "bar"
  end
  def hello
    p "hello"
  end
end

# Barの子(Fooの孫)
class Baz < Bar
  def initialize
    @name = "baz"
  end
end

foo = Foo.new
bar = Bar.new
baz = Baz.new

foo.hello
bar.hello
baz.hello
# = > "Hello:foo"
# => "hello"
# => "hello"

Bazの親クラスであるBarクラスでhelloメソッドがオーバーライドされているため Fooクラスのhelloメソッドは実行されない。

FooクラスのhelloメソッドからUnboundMethodオブジェクトを作り、それを介することで 親の親クラスであるFooのhelloメソッドを呼ぶ事ができる。

# FooのhelloメソッドのUnboundMethodを取得
um_hello = Foo.instance_method(:hello)

# BazオブジェクトのメソッドとしてFoo#helloを実行
um_hello.bind(baz).call()
# => "Hello:baz"

UnboundMethodはレシーバ(どのオブジェクトのものかという情報)を持たないのでUnboundMethod#bindで オブジェクトと結び付けます。 関係ないオブジェクトは結び付けられません。

# omake
# Bazの子(Fooのひ孫)
class Ubor < Baz
  def initialize
    @name = "ubor"
  end
  def hello
    Foo.instance_method(:hello).bind(self).call
  end
end

u = Ubor.new
u.hello
# => "Hello:ubor"

回りくどいけど競合対策で必要になる事もあるかもしれない。

aliasを使って元のメソッドのコピーをとっておくという方法もありますが名前被りがちょっと怖い。