'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 |