LoginSignup
0

More than 3 years have passed since last update.

rubyで継承した親クラスのメソッドを[super]以外の方法で呼び出したい

Last updated at Posted at 2019-08-30

問題

  1. 親クラスに子クラスで使う共通のメソッドがある
  2. 子クラスで同名のメソッドがあるが、その場合はsuperで呼べる
  3. 子クラスで全く別のメソッドから、親クラスの特定のメソッドを呼ぶ時はsuperは使えない

下の例で

  def another_method_name
    p "another_method_nameからの呼び出し"
    method_name # => これは自分自身のmethod_nameになる
  end

としたい所だが、C自身のmethod_nameを呼ぶ事になり、paramsなどが違う場合などはC#method_name経由でP#method_nameを呼ぶわけにはいかない。

# another_method_nameメソッドからはPのインスタンスメソッドとなる
# method_nameが直接呼べない。

class P
  def method_name
    p "from parent"
  end
end

class C < P
  def method_name(caller_name)
    p "calling from #{caller_name}"
    # => Pの同名メソッドが呼べる 
    # ()無しだとparamsも全部渡してしまうので、()付でparams無し
    super() 
  end

  def another_method_name
    p "another_method_nameからの呼び出し"

    # 単純に
    # method_name 
    # としてしまうと、自分自身(C)のmethod_nameを呼ぶ事になる
    # superでは自身のメソッドの親側のメソッドを呼ぶため、method_nameではない

    # P#method_nameは直接アクセスできない 
    # なので、Pクラスからmethod_nameメソッドを取り出して動的に呼ぶ
    P.instance_method(:method_name).bind(self).call
  end
end

解決方法

P.instance_method(:method_name).bind(self).call

# または動的にするなら
self.class.ancestors[1].instance_method(:method_name).bind(self).call

# 親のメソッドにparamsがあれば.call(...)で呼ぶ

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
0