Harish Shetty
Harish Shetty

Reputation: 64363

How do I call a super class method

I have two classes A, and B. Class B overrides the foo method of class A. Class B has a bar method where I want to call the foo method of the super class. What is the syntax for such a call?

class A    
 def foo
   "hello"
 end    
end


class B < A
 def foo
  super + " world"
 end

 def bar
   # how to call the `foo` method of the super class?
   # something similar to
   super.foo
 end
end

For class methods I can call the methods up the inheritance chain by explicitly prefixing the class name. I wonder if there is a similar idiom for instance methods.

class P
 def self.x
   "x"
 end
end

class Q < P
 def self.x
   super + " x"
 end

 def self.y
   P.x
 end
end

Edit My use case is general. For a specific case I know I can use alias technique. This is a common feature in Java or C++, so I am curious to know if it is possible to do this without adding extra code.

Upvotes: 35

Views: 44219

Answers (5)

Nakilon
Nakilon

Reputation: 35074

Based on @Sony's answer.

In case when you want to call the method method on some my_object and it's already overriden somewhere several classes higher (like for the Net::HTTPRequest#method), instead of doing .superclass.superclass.superclass use the:

Object.instance_method(:method).bind(my_object)

Like this:

p Object.instance_method(:method).bind(request).call(:basic_auth).source_location

Upvotes: 1

zlx_star
zlx_star

Reputation: 584

In Ruby 2.2, you can use Method#super_method now

For example:

class B < A
  def foo
    super + " world"
  end

  def bar
    method(:foo).super_method.call
  end
end

Ref: https://bugs.ruby-lang.org/issues/9781#change-48164 and https://www.ruby-forum.com/topic/5356938

Upvotes: 44

Sony Santos
Sony Santos

Reputation: 5545

You can do:

 def bar
   self.class.superclass.instance_method(:foo).bind(self).call
 end

Upvotes: 26

Arkku
Arkku

Reputation: 42129

In this particular case you can just alias :bar :foo before def foo in class B to rename the old foo to bar, but of course you can alias to any name you like and call it from that. This question has some alternative ways to do it further down the inheritance tree.

Upvotes: 14

Chuck
Chuck

Reputation: 237040

You can alias old_foo foo before redefining it to keep the old implementation around under a new name. (Technically it is possible to take a superclass's implementation and bind it to an instance of a subclass, but it's hacky, not at all idiomatic and probably pretty slow in most implementation to boot.)

Upvotes: 6

Related Questions