2017-10-18 114 views
3

說我要修補的Kernel模塊與一個方法我只是想出了Ruby的內核模塊的方法但我也可以做以下我通常不應該做的事情:作爲Object類的方法

Object.say_hello # => hello world 

由於Object包括Kernel它採用其實例方法,因此所有Object實例都應響應say_hello。到現在爲止還挺好。

然而Object.say_hello似乎是一個類的方法,如果我們做了類似的事情這可能纔是合理的:

class << Object 
    def say_hello 
    puts "hello world" 
    end 
end 

存儲在Object的單例類say_hello將允許我們使用它作爲一個類方法,而是Kernel只包含在Object中,不應該允許這種行爲。但它確實如此。有人知道爲什麼嗎?

感謝

+3

這很簡單:''Object''是'Class',它是'Object'。這就是爲什麼它響應'say_hello' :) –

回答

5

Kernel只是包含在Object [...]

這是正確的。

[...]它不應該允許這種行爲。

你忽略了類也是對象。


順其自然的say_hello方法來源於如果objObject一個實例:

obj = Object.new 

obj.method(:say_hello) 
#=> #<Method: Object(Kernel)#say_hello> 

正如預期。objObject一個實例,並Object包括Kernel

obj.class.include? Kernel 
#=> true 

obj.class.ancestors 
#=> [Object, Kernel, BasicObject] 

現在讓我們來看看obj是類Object會發生什麼:

obj = Object 

obj.method(:say_hello) 
#=> #<Method: Class(Kernel)#say_hello> 

這次objClassClass實例還包括Kernel

obj.class.include? Kernel 
#=> true 

obj.class.ancestors 
#=> [Class, Module, Object, Kernel, BasicObject] 

Ruby的documentation指出,類方法實際上是類對象上定義只是實例方法:(強調)

class C 
    def self.my_method 
    # ... 
    end 
end 

然而,這是一個更大的只是一個特例Ruby中的語法能力,可以將方法添加到任何對象。類是對象,因此添加類方法只是將方法添加到類對象

相關問題