为什么允许在 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 程序本身定义了一个名为 main
的 Object
实例,它用作定义您的方法的顶级范围。因此,如果您将程序视为 运行 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 之间发生了变化,但不影响方法公开。
我读了这个:
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 程序本身定义了一个名为 main
的 Object
实例,它用作定义您的方法的顶级范围。因此,如果您将程序视为 运行 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 之间发生了变化,但不影响方法公开。