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

nop*_*ole 5 ruby

例如,如果我们

def c=(foo)
  p "hello"
end

c = 3
c=(3)
Run Code Online (Sandbox Code Playgroud)

并且不打印"你好".我知道它可以被调用,self.c = 3但为什么呢?以及在其他方面可以调用它?

sep*_*p2k 8

c = 3(并且c = (3),它完全等同于它)始终被解释为局部变量赋值.您可能会说只有c=在自己没有定义方法时才应该将其解释为局部变量赋值,但是存在各种问题:

  1. 至少MRI需要在​​分析时知道在给定范围内定义了哪些局部变量.但是,在解析时不知道是否定义了给定方法.所以ruby无法知道是c = 3定义变量c还是调用方法c=直到运行时,这意味着它不知道是否c在分析时定义了局部变量.这意味着MRI需要改变它在解析器中处理局部变量的方式,以使其像你想要的那样工作.

  2. c如果c=已定义方法,则无法定义命名的局部变量.你可能会说这没关系,因为无论如何都要使用同名的局部变量和方法.然而考虑的情况下,这里定义method_missing,以便foo=为每个可能的FOO定义(如对案件OpenStructS表示例子).在这种情况下,根本无法定义局部变量.

  3. 你无法确定一个对象是否响应而c=没有运行它,因为它可能会被处理method_missing.所以整件事实际上是不可判定的.

  • +1给出一个全面的原因列表(而我只提供行为/规则本身). (2认同)

Ed *_* S. 7

因为局部变量优先于先前定义的具有相同名称的方法/变量.在这种情况下,您需要使用'self'进行限定,以便c不被解释为局部变量的声明/赋值.

  • 他发布的代码就足够了.如果你做了'self.c = 3`,它就可以在IRB中运行. (2认同)