ruby顶层定义的方法在哪里?
在顶层,方法定义应该导致Object
上的私有方法,并且测试似乎证实了这一点:
def hello; "hello world"; end Object.private_instance_methods.include?(:hello) #=> true Object.new.send(:hello) #=> "hello world"
但是,以下也适用于顶层( self.meta
是main
本征类):
self.meta.private_instance_methods(false).include?(:hello) #=> true
似乎hello
方法同时在main和Object
本征类上定义。 这是怎么回事? 请注意, private_instance_methods
的false
参数会从方法列表中排除超类方法。
首先,这种行为和潜在的推理一直存在; 这对1.9来说并不新鲜。 它发生的技术原因是因为main
是特殊的,并且处理方式与任何其他对象不同。 没有花哨的解释:它的行为方式是因为它是这样设计的。
好的,但为什么呢? main
神奇的原因是什么? 因为Ruby的设计师Yukihiro Matsumoto认为它使语言更好地具有这种行为:
是这样,为什么顶级方法不在这个对象上制作单例方法,而不是作为Object类本身的实例方法(因此被引入所有其他类,即比通常预期更多的命名空间污染)。 这仍然允许顶级方法调用其他顶级方法。 如果顶层对象被像Main这样的常量引用,则可以使用Main.method(…)从任何地方调用这些方法。
你真的希望到处输入“Main.print”吗?
在讨论中,他解释说它的行为方式是因为他觉得“假设是自然的”。
编辑:
在回答您的评论时,您的问题是针对为什么main的本征类似乎将hello
作为私有实例方法报告。 问题在于,没有任何顶级函数实际添加到main
,而是直接添加到Object
。 当使用本征类时, instance_methods
函数族总是表现得好像本征类仍然是原始类。 也就是说,类中定义的方法被视为直接在本征类中定义。 例如:
class Object private def foo "foo" end end self.send :foo # => "foo" Object.private_instance_methods(false).include? :foo # => true self.meta.private_instance_methods(false).include? :foo # => true class Bar private def bar "bar" end end bar = Bar.new bar.send :bar # => "bar" Bar.private_instance_methods(false).include? :bar # => true bar.meta.private_instance_methods(false).include? :bar # => true
但是我们可以直接在main
的本征类中添加一个方法。 将您的原始示例与此进行比较:
def self.hello; "hello world"; end Object.instance_methods.include? :hello # => false self.meta.instance_methods.include? :hello # => true
好的,但是如果我们真的想知道给定的函数是在本征类上定义的,而不是原始的类呢?
def foo; "foo"; end #Remember, this defines it in Object, not on main def self.bar; "bar"; end #This is defined on main, not Object foo # => "foo" bar # => "bar" self.singleton_methods.include? :foo # => false self.singleton_methods.include? :bar # => true