ruby顶层定义的方法在哪里?

在顶层,方法定义应该导致Object上的私有方法,并且测试似乎证实了这一点:

 def hello; "hello world"; end Object.private_instance_methods.include?(:hello) #=> true Object.new.send(:hello) #=> "hello world" 

但是,以下也适用于顶层( self.metamain本征类):

 self.meta.private_instance_methods(false).include?(:hello) #=> true 

似乎hello方法同时在main和Object本征类上定义。 这是怎么回事? 请注意, private_instance_methodsfalse参数会从方法列表中排除超类方法。

首先,这种行为和潜在的推理一直存在; 这对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