Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby : Invoke overridden method of parent class, in child class

Tags:

ruby

Say I have class B derived from class A

Is it possible to invoke overrided method of A like this?

class A
  def method1
  end
  def method2
  end
end

class B < A
  def method1
  ### invoke method2 of class A is what I want to do here
  end
  def method2
  end
end

# not exactly duplicate to How do I call an overridden parent class method from a child class? , but we seem want to do the same thing.

like image 494
Jokester Avatar asked Dec 23 '11 13:12

Jokester


3 Answers

I'm assuming here that B is supposed to inherit from A and you simply made a typo in your example code. If this is not the case, there is no way to do what you want.

Otherwise you can do what you want using reflection by binding A's method2 instance method to your current B object and calling it like this:

class A
  def method1
  end
  def method2
  end
end

class B < A
  def method1
    A.instance_method(:method2).bind(self).call
  end
  def method2
  end
end

Note though that you shouldn't pull out the big black-magic-guns like this unless you really need to. In most cases redesigning your class hierarchy so that you don't need to do this is the better alternative.

like image 121
sepp2k Avatar answered Nov 14 '22 21:11

sepp2k


You can create a synonym for parent method using alias statement and call it from the overriden method:

class A
  def method1
    puts '1'
  end
  def method2
    puts '2'
  end
end

class B < A
  alias parent_method1 method1
  alias parent_method2 method2
  def method1
    parent_method2
  end
  def method2
  end
end

b = B.new
b.method1 # => 2
like image 42
Aliaksei Kliuchnikau Avatar answered Nov 14 '22 21:11

Aliaksei Kliuchnikau


The answer of @sepp2k is technically correct, however I would like to explain why this technique is not appropriate in my opinion (so the question is technically interesting, but leads to the wrong goal):

  • Ruby does not allow to call super.method2 in the context of method1called in an instance of B, because it is just wrong to do it. Class inheritance should be used when your instances are specializations of the superclass. That includes that you normally only expand behavior, by calling super and doing something additionally before or after that call.
  • There are languages like Java and others, that allow to call super for another method, and that leads to something similar to spaghetti code, but the object-oriented way. No one understands when which methods are called, so try to avoid it.

So try to find the reason why you want to change the call, and fix that. If your method1 in A is wrong implemented in B, then you should not subclass is.

like image 22
mliebelt Avatar answered Nov 14 '22 19:11

mliebelt