首先,这种行为和背后的推理一直存在;这对 1.9 来说并不是什么新鲜事。它发生的技术原因是因为main 是特殊的,并且与任何其他对象都不同。没有花哨的解释:它的行为方式是这样的,因为它是这样设计的。
好的,但是为什么呢? main 神奇的原因是什么?因为 Ruby 的设计师 Yukihiro Matsumoto 认为 makes the language better 有这种行为:
是这样,为什么顶级方法没有在这个对象上做成单例方法,
而不是作为 Object 类的实例方法引入
本身
(因此进入所有其他类,即比现在更多的命名空间污染
通常是有意的)。这仍然允许顶级方法调用其他方法
顶级方法。如果顶级对象被引用
一些
像 Main 这样的常量,那么可以从任何地方调用这些方法
和
Main.method(...).
你真的想输入
“Main.print”无处不在?
在进一步的讨论中,他解释说它的行为方式是因为他觉得“假设是自然的”。
编辑:
针对您的评论,您的问题是针对为什么 main 的 eigenclass 似乎将 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
好的,但是如果我们真的想知道给定函数是在 eigenclass 上定义的,而不是在原始类上定义的呢?
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