【问题标题】:Why are global methods allowed to be defined outside of a class in Ruby?为什么允许在 Ruby 中的类之外定义全局方法?
【发布时间】:2015-03-02 06:47:11
【问题描述】:

我读到了:

让我们从一个简单的 Ruby 程序开始。我们将编写一个方法 返回一个愉快的、个性化的问候。

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

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

那么,如果它没有在类中定义,它怎么可能是一个方法呢?

【问题讨论】:

  • 回想一下,方法返回最后计算的值。出于这个原因,这个方法通常写成def say_goodnight(name); "Goodnight, " + name; end。此外,您经常会看到第二行写成"Goodnight, #{ name }""Goodnight, %s" % name

标签: ruby object


【解决方案1】:

当您在 Ruby 中以这种方式在全局范围内定义一个函数时,它在技术上变成了 Object 类的 private 方法,这是 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 可见性的方法,所以只能在定义它的类或子类的对象内部调用它。那么为什么它似乎在全球范围内可用?

基本上,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 将在此示例中使用 public 可见性而不是 private 定义方法 Object#say_goodnight。这种行为似乎在 Ruby 2.2.x 和 2.3.x 之间发生了变化,但不影响方法公开。

【讨论】:

  • 私有与继承无关。
  • 当我使用 ruby​​-2.6.5 在irb 中运行这些代码时,方法被定义为public
  • @lfx_cool 我可以确认。我必须调查更改发生的时间并相应地更新答案
猜你喜欢
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2012-09-02
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多