Reputation: 4665
Consider this code:
class Hello
def hi
puts "Hello"
end
end
class HelloWorld < Hello
def hi
super.hi
puts "World"
end
end
HelloWorld.new.hi
Gives output:
$ ruby super.rb
Hello
super.rb:9:in `hi': undefined method `hi' for nil:NilClass (NoMethodError)
from super.rb:14:in `<main>'
Why does Hello get printed? I would expect to just get the error. Also I know that what I really should be doing is just calling super
instead of super.hi
but I want to understand what is happening "under the hood".
Upvotes: 1
Views: 850
Reputation: 118271
super.hi
is only the method chaining you put inside the class HelloWorld
.The call to super
is valid,but on return value from super call,is nil
due to puts
statement.And then nil.hi
is the culprit.
class Hello
def hi
puts "Hello"
end
end
class HelloWorld < Hello
def hi
super.hi
puts "World"
end
end
HelloWorld.new.hi
# ~> -:9:in `hi': undefined method `hi' for nil:NilClass (NoMethodError)
This is because super
method is called first,which produces the output Hello
,by calling Hello#hi
. Now puts "Hello"
made the super
method to return nil
. NilClass
don't have the hi
method,thus nil.hi
throws error. See now the same thing with different taste.
class Hello
def hi
p "Hello"
end
end
class HelloWorld < Hello
def hi
super.hi
puts "World"
end
end
HelloWorld.new.hi
# ~> -:9:in `hi': undefined method `hi' for "Hello":String (NoMethodError)
# ~> from -:14:in `<main>'
# >> "Hello"
Here I changed the puts
to p
,so now as per the convention p "Hello"
returns the "Hello"
String itself,unlike puts
.But the error is definite,as String
class don't have the method hi
,so the now "Hello".hi
throws the legitimate error.
Upvotes: 0
Reputation: 38586
super
already automatically calls the method that is being overridden. What's happening is that hi
in Hello
returns nil
, because it simply did puts
which returns nil
(and it's the last expression). So Ruby evaluates super
, which calls the method, and then it tries to access the hi
method from the resulting nil
object, and there is none.
Upvotes: 7