68

I've used super to initialize parent class but I cannot see any way of calling parent class from subclass methods.

I know PHP and other languages do have this feature but cannot find a good way to do this in Ruby.

What would one do in this situation?

Passionate Engineer
  • 10,034
  • 26
  • 96
  • 168

6 Answers6

107

If the method is the same name, i.e. you're overriding a method you can simply use super. Otherwise you can use an alias_method or a binding.

class Parent
  def method
  end
end

class Child < Parent
  alias_method :parent_method, :method
  def method
    super
  end

  def other_method
    parent_method
    #OR
    Parent.instance_method(:method).bind(self).call
  end
end
Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104
Mark Meyer
  • 3,643
  • 3
  • 23
  • 34
  • This doesn't work. `Child.new.other_method` returns `NoMethodError: super: no superclass method 'other_method' for #`. The call to `super.method()` will only call `method` on whatever gets returned from the call to `super` (which, in this case, doesn't exist). `super` is not a reference to an instance's `superclass`. – Cade Aug 26 '13 at 19:07
  • 1
    Also calling `super` will call super with exact arguments that was passed to the child method. If you want to specify specify arguments you can by calling super with them: EG: `def child(a, b); super; end` vs `def child(a, b); super(somevar); end` – Adam Nov 02 '15 at 22:59
22

The super keyword calls a method of the same name in the super class:

class Foo
  def foo
    "#{self.class}#foo"
  end
end

class Bar < Foo
  def foo
    "Super says: #{super}"
  end
end

Foo.new.foo # => "Foo#foo"
Bar.new.foo # => "Super says: Bar#foo"
maerics
  • 151,642
  • 46
  • 269
  • 291
18

The super keyword in Ruby actually calls a method of the same name in the parent class. (source)

class Foo
  def foo
    # Do something
  end
end

class Bar < Foo
  def foo
    super # Calls foo() method in parent class
  end
end
Magne
  • 16,401
  • 10
  • 68
  • 88
Graham Swan
  • 4,818
  • 2
  • 30
  • 39
  • 11
    Putting an example in Java is not the best idea if the requester explicitly mentions PHP as other language he knows... – bert bruynooghe Mar 07 '14 at 13:01
  • 1
    this answer was helpful to me, and he says he knows PHP AND other languages have this feature (not that he only knows PHP). – Jared Menard Jul 21 '15 at 15:22
17

Others have said it already well. Just one additional note of caution:

The syntax super.foo to call method foo in the super class is not supported. Rather it will call the super-method and on the returned result, try to call foo.

  class A
    def a
      "A::a"
    end
  end

  class B < A
    def a
      "B::a is calling #{super.a}" # -> undefined method `a` for StringClass 
    end
  end
Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
  • 4
    This is an important distinction people should be aware of, so thanks for pointing this out! – Magne Nov 20 '17 at 16:30
7
class Parent
  def self.parent_method
    "#{self} called parent method"
  end

  def parent_method
    "#{self} called parent method"
  end
end

class Child < Parent

  def parent_method
    # call parent_method as
    Parent.parent_method                # self.parent_method gets invoked
    # call parent_method as
    self.class.superclass.parent_method # self.parent_method gets invoked
    super                               # parent_method gets invoked 
    "#{self} called parent method"      # returns "#<Child:0x00556c435773f8> called parent method"
  end

end

Child.new.parent_method  #This will produce following output
Parent called parent method
Parent called parent method
#<Child:0x00556c435773f8> called parent method
#=> "#<Child:0x00556c435773f8> called parent method"

self.class.superclass == Parent #=> true

Parent.parent_method and self.class.superclass will call self.parent_method(class method) of Parent while super calls the parent_method(instance method) of Parent.

Aravind Vemula
  • 1,571
  • 17
  • 22
5

As of Ruby 2.2, super_method can also be used to call super of method a from method b.

method(:a).super_method.call
konsolebox
  • 72,135
  • 12
  • 99
  • 105