为什么允许在 Ruby 中的 class 之外定义全局方法?

Why are global methods allowed to be defined outside of a class in Ruby?

我读了这个:

Let’s start with a simple Ruby program. We’ll write a method that returns a cheery, personalized greeting.

def say_goodnight(name)
    result = "Goodnight, " + name
    return result
end

我的理解是,方法是定义在class中的函数或子例程,可以关联到class(class方法)或对象(实例方法)。

那么,如果它不是在 class 中定义的,怎么会是一个方法呢?

当您以这种方式在全局范围内定义 Ruby 中的函数时,它在技术上成为 Object class 的 private 方法,这是基础 class 一切都继承自 Ruby。 Everything in Ruby is an object,你确实定义了一个方法

def say_goodnight(name)
    result = "Goodnight, " + name
    return result
end

Object.private_methods.include? :say_goodnight
=> true

因为它被定义为在 Object 上具有 private 可见性的方法,所以它只能在定义它的 class 或子 [=44= 的对象内部调用]是的。那么为什么它似乎在全球范围内可用?

基本上,Ruby 程序本身定义了一个名为 mainObject 实例,它用作定义您的方法的顶级范围。因此,如果您将程序视为 运行 inside main(这是一个 Object),它的私有方法可供使用。

# In irb:
self
=> main
self.class
=> Object
self.private_methods.include? :say_goodnight
=> true

附录: This answer 进一步解释了 main 是如何定义和实现的。

更新 Ruby >= 2.3

在评论线程中指出,Ruby 的更高版本将在此示例中定义方法 Object#say_goodnight,具有 public 可见性而不是 private。此行为似乎在 Ruby 2.2.x 和 2.3.x 之间发生了变化,但不影响方法公开。