class A def a puts 'in #a' end end class B < A def a b() end def b # here i want to call A#a. end end
Asked
Active
Viewed 2.2k times
3 Answers
87
class B < A
alias :super_a :a
def a
b()
end
def b
super_a()
end
end

Beffa
- 915
- 1
- 8
- 18
-
To alias a class method, see http://stackoverflow.com/questions/2925016/alias-method-and-class-methods-dont-mix – Jared Beck Feb 14 '14 at 01:47
-
1Is it possible that `alias` has been renamed to [`alias_method`](http://apidock.com/ruby/Module/alias_method) since this answer was written? – Jared Beck Feb 14 '14 at 01:49
-
@JaredBeck it really has been renamed. So now it should be: alias_method :super_a :a – evgeny.myasishchev Sep 09 '14 at 21:01
-
There is a strange thing. In the api doc for [ruby 2.1.2](http://ruby-doc.org/core-2.1.2) there is no alias method, but running code with alias works. Maybe I'm checking some wrong doc? – evgeny.myasishchev Sep 09 '14 at 21:07
-
3Why does this work? Why does this not alias `:super_a` to `B.a` and instead aliases it to `A.a`? – Marko Avlijaš Jan 17 '17 at 08:23
-
3@MarkoAvlijaš at the time you are creating the alias, `B.a` isn't defined yet... not the case if you put the `alias` below the `def a` – hurrycaner Mar 18 '17 at 04:35
32
There's no nice way to do it, but you can do A.instance_method(:a).bind(self).call
, which will work, but is ugly.
You could even define your own method in Object to act like super in java:
class SuperProxy
def initialize(obj)
@obj = obj
end
def method_missing(meth, *args, &blk)
@obj.class.superclass.instance_method(meth).bind(@obj).call(*args, &blk)
end
end
class Object
private
def sup
SuperProxy.new(self)
end
end
class A
def a
puts "In A#a"
end
end
class B<A
def a
end
def b
sup.a
end
end
B.new.b # Prints in A#a

sepp2k
- 363,768
- 54
- 674
- 675
-
8@klochner I disagree, this solution was exactly what I needed... reason: I wanted to generically call super method of a different method, but without the need to alias every single one that I wanted to be able to do this for, so a generic way to invoke super is pretty useful – Mike Stone Sep 27 '10 at 19:32
-
4Complicated to define once, simple to call it lots of times. That's better than vice versa. – Grant Hutchins Sep 16 '11 at 16:10
1
If you don't explicitly need to call A#a from B#b, but rather need to call A#a from B#a, which is effectively what you're doing by way of B#b (unless you're example isn't complete enough to demonstrate why you're calling from B#b, you can just call super from within B#a, just like is sometimes done in initialize methods. I know this is kind of obvious, I just wanted to clarify for any Ruby new-comers that you don't have to alias (specifically this is sometimes called an "around alias") in every case.
class A
def a
# do stuff for A
end
end
class B < A
def a
# do some stuff specific to B
super
# or use super() if you don't want super to pass on any args that method a might have had
# super/super() can also be called first
# it should be noted that some design patterns call for avoiding this construct
# as it creates a tight coupling between the classes. If you control both
# classes, it's not as big a deal, but if the superclass is outside your control
# it could change, w/o you knowing. This is pretty much composition vs inheritance
end
end

kernelsmith
- 87
- 3