Reputation: 64363
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
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
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
Reputation: 5545
You can do:
def bar
self.class.superclass.instance_method(:foo).bind(self).call
end
Upvotes: 26
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
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