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]
注:很明顯,荷蘭國際集團include
到Kernel
的Object
一個實例,實際上並不做什麼什麼,因爲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
方法,也沒有一個在它的祖先鏈。 include
是Module
類的一種方法,但obj
是Object
,而不是Module
。
你對私人方法的解釋是最好的,對我來說完全有意義,謝謝你的偉大答案! – mko
@jorg請你看看我的[post](http://stackoverflow.com/questions/15419429/confusion-with-singleton-method-defined-on-class-object/15445800?noredirect=1#15445800)嗎? –