2011-07-22 189 views
3

的一個實例。在頂級的:爲什麼我不能包括內核的單例類對象

unbinded_method = method :puts 

#=> Object(Kernel)#puts(*arg1) 

,但我這樣做

obj = Object.new 

obj.puts 'wow' 

我得到了一個未定義的錯誤

所以我假設內核模塊沒有包含在obj的單例類中,所以我做了

obj.instance_eval do 

include Kernel 

end 

但我得到了一次錯誤:

NoMethodError: undefined method `include' for #<Object:0x00000100b14dc8> 

回答

5

Why can't I include Kernel in the singleton class of an instance of Object

嗯,你可以

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

class << obj 
    include Kernel 
end 
obj.singleton_class.ancestors 
# => [Object, Kernel, BasicObject] 

注:很明顯,荷蘭國際集團includeKernelObject一個實例,實際上並不做什麼什麼,因爲Kernel已經在祖先鏈中,而mixin只能在祖先鏈中出現一次。但是,如果你include另一個混入,將工作:

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

class << obj 
    include Enumerable 
end 
obj.singleton_class.ancestors 
# => [Enumerable, Object, Kernel, BasicObject] 

but I did this

obj = Object.new 

obj.puts 'wow' 

I got an undefined error

不,你沒有。這是你得到的錯誤:它告訴你那裏錯誤

# NoMethodError: private method `puts' called for #<Object:0xdeadbed> 

問題是什麼:Kernel#puts是私有的,而在Ruby中,私有方法只能被調用爲receiverless消息的結果發送。例如像這樣:

obj.instance_eval do puts 'wow' end 
# wow 

或只是

obj.send :puts, 'wow' # send cirvumvents access protection 
# wow 

so I assumed the Kernel module didn't include in the singleton class of obj [...]

你爲什麼要承擔,而不是僅僅檢查?

obj.singleton_class.ancestors.include? Kernel # => true 

so I did

obj.instance_eval do 
    include Kernel 
end 

but I got error again:

NoMethodError: undefined method `include' for #

同樣,錯誤信息已經告訴你,你需要知道的一切:Object沒有一個include方法,也沒有一個在它的祖先鏈。 includeModule類的一種方法,但objObject,而不是Module

+0

你對私人方法的解釋是最好的,對我來說完全有意義,謝謝你的偉大答案! – mko

+0

@jorg請你看看我的[post](http://stackoverflow.com/questions/15419429/confusion-with-singleton-method-defined-on-class-object/15445800?noredirect=1#15445800)嗎? –

相關問題