1

考虑这段代码:

class Hello
  def hi
    puts "Hello"
  end
end

class HelloWorld < Hello
  def hi
    super.hi
    puts "World"
  end
end

HelloWorld.new.hi

给出输出:

$ ruby super.rb
Hello
super.rb:9:in `hi': undefined method `hi' for nil:NilClass (NoMethodError)
    from super.rb:14:in `<main>'

为什么要打印 Hello?我希望只会得到错误。我也知道我真正应该做的只是打电话super而不是打电话,super.hi但我想了解“幕后”发生的事情。

4

2 回答 2

7

super已经自动调用被覆盖的方法。发生的事情是hi在return 中,因为它只是做了which 返回Hello(它是最后一个表达式)。所以 Ruby 评估,它调用该方法,然后它尝试从结果对象访问该方法,但没有。nilputsnilsuperhinil

于 2013-07-27T22:14:33.240 回答
0

super.hi只是你放在类中的方法链接HelloWorld。调用super是有效的,但是超级调用的返回值是nil由于puts语句。然后nil.hi是罪魁祸首。

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)

这是因为super方法首先被调用,它Hello通过调用产生输出Hello#hi。现在puts "Hello"制作了super返回的方法nilNilClass没有该hi方法,因此nil.hi会引发错误。现在看到同样的东西有不同的味道。

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"

在这里,我将其更改putsp,所以现在按照惯例p "Hello"返回"Hello"字符串本身,不像puts。但是错误是确定的,因为String类没有方法hi,所以现在"Hello".hi抛出合法错误。

于 2013-07-27T22:12:29.333 回答