在顶级:
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>
答案 0 :(得分:5)
为什么我不能在Object
的实例的单例类中包含Kernel
嗯,你可以:
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
并不实际做任何事情,因为include
是已经在祖先链中,而mixins只能在祖先链中出现一次。但是如果你obj = Object.new
obj.singleton_class.ancestors
# => [Object, Kernel, BasicObject]
class << obj
include Enumerable
end
obj.singleton_class.ancestors
# => [Enumerable, Object, Kernel, BasicObject]
另一个 mixin,那将会有效:
obj = Object.new
obj.puts 'wow'
但我这样做了
# NoMethodError: private method `puts' called for #<Object:0xdeadbed>
我收到了一个未定义的错误
不,你没有。这是你得到的错误:
Kernel#puts
它告诉你就在那里错误是什么问题:obj.instance_eval do puts 'wow' end
# wow
是私有的,而在Ruby中,私有方法只能作为无接收消息发送的结果来调用。例如:
obj.send :puts, 'wow' # send cirvumvents access protection
# wow
或只是
obj.singleton_class.ancestors.include? Kernel # => true
所以我假设内核模块没有包含在obj [...]
的单例类中
你为什么假设而不仅仅是检查?
obj.instance_eval do
include Kernel
end
所以我做了
Object
但我又错了:
NoMethodError:未定义的方法`include'for#
同样,错误消息已经告诉您需要知道的所有内容:include
没有include
方法,其祖先链中也没有。{1}}。 Module
是obj
类的一种方法,但Object
是Module
,而不是{{1}}。