ruby - 在 Ruby 中,如果我们定义了一个方法调用 "c=",为什么 c = 3 不能调用它?

标签 ruby

例如,如果我们

def c=(foo)
  p "hello"
end

c = 3
c=(3)

并且不会打印“hello”。我知道它可以被 self.c = 3 调用,但为什么呢?可以通过哪些其他方式调用它?

最佳答案

c = 3(和 c = (3),完全等同于它)总是被解释为局部变量赋值。你可能会说只有当方法 c= 没有在 self 上定义时,它才应该被解释为局部变量赋值,但是这有很多问题:

  1. 至少 MRI 需要在解析时知道在给定范围内定义了哪些局部变量。但是,在解析时并不知道给定的方法是否已定义。所以 ruby​​ 直到运行时才知道 c = 3 是否定义了变量 c 或者调用了方法 c= ,这意味着它不会知道在解析时是否定义了局部变量 c。这意味着 MRI 需要更改它在解析器中处理局部变量的方式,以使其按您希望的方式工作。

  2. 如果c= 方法已经定义,则不可能定义名为c 的局部变量。您可能会说这没关系,因为具有相同名称的局部变量和方法无论如何都会造成混淆。但是请考虑这种情况,您定义 method_missing 以便为每个可能的 foo 定义 foo=(例如 OpenStruct 的情况) ).在那种情况下,根本不可能定义局部变量。

  3. 您无法确定对象是否响应 c= 而不运行它,因为它可能由 method_missing 处理。所以整个事情实际上是无法确定的。

关于ruby - 在 Ruby 中,如果我们定义了一个方法调用 "c=",为什么 c = 3 不能调用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5111350/

相关文章:

ruby - Jekyll 的所有功能都不再起作用

ruby-on-rails - 如果我们将参数缓存到操作中的本地变量中,它会有所帮助还是相同?

ruby - 无法在 Ruby 代码中对数组进行排序

ruby - 获取季度的开始/结束日期

ruby - 使用 Chef 进行 SSL 证书条件检查

ruby - 如何在类名中使用带空格的 CSS 选择器

ruby - 如何以编程方式添加文本,就像复制粘贴一样?

ruby - 在Ruby中实现过程输出的最佳方法

ruby - case 语句与 Ruby 中的哈希查找的优缺点是什么?

ruby - Sinatra 与 EventMachine WebSockets 一起使用是否成功?