在Ruby中,如果我们定义一个方法调用;c=“c”;,为什么可以';它不能被c=3调用吗?

在Ruby中,如果我们定义一个方法调用;c=“c”;,为什么可以';它不能被c=3调用吗?,ruby,Ruby,例如,如果我们 def c=(foo) p "hello" end c = 3 c=(3) 并且不会打印“你好”。我知道self.c=3可以调用它,但为什么呢?还有什么方法可以调用它呢?因为局部变量优先于先前定义的同名方法/变量。在这种情况下,您需要使用“self”进行限定,这样c就不会被解释为局部变量的声明/赋值。Ruby只在代码不能被解释为变量赋值的情况下调用这种方法。没有更好的方法来强制方法调用 self.c = 1 send(:c=, 1) __send__(:c=, 1) me

例如,如果我们

def c=(foo)
  p "hello"
end

c = 3
c=(3)

并且不会打印“你好”。我知道self.c=3可以调用它,但为什么呢?还有什么方法可以调用它呢?

因为局部变量优先于先前定义的同名方法/变量。在这种情况下,您需要使用“self”进行限定,这样c就不会被解释为局部变量的声明/赋值。

Ruby只在代码不能被解释为变量赋值的情况下调用这种方法。没有更好的方法来强制方法调用

self.c = 1
send(:c=, 1)
__send__(:c=, 1)
method(:c=).call(1)
method(:c=)[1]
c=3
(与之完全等效的
c=(3)
)始终被解释为局部变量赋值。您可能会说,只有在self上未定义方法
c=
时,才应将其解释为局部变量赋值,但存在各种问题:

  • 至少MRI需要在解析时知道在给定范围内定义了哪些局部变量。然而,在解析时不知道是否定义了给定的方法。因此,ruby直到运行时才知道
    c=3
    是否定义了变量
    c
    ,或者调用了方法
    c=
    ,这意味着它不知道是否在解析时定义了局部变量
    c
    。这意味着MRI需要改变它在解析器中处理局部变量的方式,以使它像您希望的那样工作

  • 如果已经定义了方法is
    c=
    ,则无法定义名为
    c
    的局部变量。您可能会说这没关系,因为使用相同名称的局部变量和方法会让人困惑。但是,考虑这样的情况,在这里定义“代码>方法>缺失<代码>,以便为每个可能的FO定义<代码> Foo= (例如,在<代码> OpenStult s)上。在这种情况下,根本不可能定义局部变量

  • 您无法确定对象是否在不运行它的情况下响应
    c=
    ,因为它可能由
    method\u missing
    处理。所以整个事情实际上是无法确定的


  • +1给出了原因的综合列表(而我只提供了行为/规则本身)。他发布的代码就足够了。如果你做了self.c=3,它会在IRB中起作用。另外,人们应该投票支持sepp2k的答案。它比我的更好、更完整。可能是我的复制品