在顶层:
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>
最佳答案
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
ing Kernel
到 Object
的实例中实际上做任何事情,因为 Kernel
already 在祖先链中,mixins 在祖先链中只能出现一次。但是,如果您包含
另一个 mixin,那将起作用:
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
是私有(private)的,在 Ruby 中,私有(private)方法只能作为以下结果调用无接收器消息发送。例如像这样:
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
.
关于ruby - 为什么我不能在 Object 实例的单例类中包含 Kernel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6790583/