'Ruby return statement does not work with super keyword?

class Parent
  def test
    return
  end
end

class Child < Parent
  def test
    super
    p "HOW IS THIS POSSIBLE?!"
  end
end

c = Child.new
c.test

I though that, since the test method from the Parent class immediately uses the return statement, it should not be possible to print the line of the Child class. But it is indeed printed. Why is that?

Ruby 1.8.7, Mac OSX.



Solution 1:[1]

super acts like a method call that calls the superclass's method implementation. In your example, the return keyword returns from Parent::test and continues executing Child::test, just like any other method call would.

Solution 2:[2]

Another way to think of the call to super in this context is if it were any other method:

class Parent
  def foo
    return
  end
end

class Child < Parent
  def test
    foo
    p "THIS SEEMS TOTALLY REASONABLE!"
  end
end

c = Child.new
c.test
# => "THIS SEEMS TOTALLY REASONABLE!"

If you really wanted to prevent the call to p, you need to use the return value from super in a conditional:

class Parent
  def test
    return
  end
end

class Child < Parent
  def test
    p "THIS SEEMS TOTALLY REASONABLE!" if super
  end
end

c = Child.new
c.test
# => nil

Solution 3:[3]

Here's a way to work around it using yield and block. ?

class Parent
  def test
    return
    yield
  end
end

class Child < Parent
  def test
    super do
      p "HOW IS THIS POSSIBLE?!"
    end
  end
end

Solution 4:[4]

This is a mater of ancestors order.

An other way to allow an early return from supercharged method would be to use module/concern implementation (instead of inheritance) and to prepend it (and not include).

class TestConcern
  def test
    return
    super # this line will never be executed
  end
end

class Child
  prepend TestConcern
  def test
    p "THIS LINE WILL NOT BE PRINTED... (but it's quite an obfuscated behaviour)"
  end
end

BTW, I find this obfuscate rather than simplify.

Solution 5:[5]

You could use exceptions

class Parent
  class ReturnEvent < RuntimeError;end

  def test
    raise ReturnEvent
  end
end

class Child < Parent
  def test
    super
    p "HOW IS THIS POSSIBLE?!"
    rescue ReturnEvent
  end
end

c = Child.new
c.test

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 benzado
Solution 2 Cade
Solution 3 ANDY CHONG
Solution 4
Solution 5 Vecchia Spugna