2013-07-27 67 views
1

考慮以下代碼:試圖使用Ruby超級調用方法直接

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

爲什麼你好得到印?我希望只是得到錯誤。此外,我知道我真的應該做的只是撥打super而不是super.hi,但我想了解「引擎蓋下」發生了什麼。

回答

7

super已自動調用正在被覆蓋的方法。發生了什麼事hiHello返回nil,因爲它只是做puts它返回nil(這是最後一個表達式)。因此,Ruby評估調用該方法的super,然後嘗試從得到的nil對象訪問hi方法,但沒有。

+0

謝謝!這是完全合理的。 –

0

super.hi僅僅是方法鏈接你把類HelloWorld .The電話裏面super是有效的,但在返回值從超級呼叫,是nil由於puts statement.And然後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引發合法錯誤。