在Ruby中,如果我们定义一个方法调用“c =”,为什么它不能被c = 3调用?
例如,如果我们
def c=(foo) p "hello" end c = 3 c=(3)
并且不打印“你好”。 我知道它可以被self.c = 3
调用,但为什么呢? 以及在其他方面可以调用它?
c = 3
(和c = (3)
,它完全等价)总是被解释为局部变量赋值。 您可能会说只有在方法c=
未在self上定义时才应将其解释为局部变量赋值,但是存在各种问题:
-
至少MRI需要在分析时知道在给定范围内定义了哪些局部变量。 但是,在解析时不知道是否定义了给定方法。 所以ruby无法知道
c = 3
是否定义变量c
或者调用方法c=
直到运行时,这意味着它不知道是否在解析时定义了局部变量c
。 这意味着MRI需要改变它在解析器中处理局部变量的方式,以使其像你想要的那样工作。 -
如果已定义方法
c=
则无法定义名为c
的局部变量。 您可能会说这没关系,因为无论如何都要使用同名的局部变量和方法。 但是请考虑这种情况,您可以在其中定义method_missing
以便为每个可能的foo定义foo=
(例如,在OpenStruct
上就是这种情况)。 在这种情况下,根本无法定义局部变量。 -
您无法确定对象是否响应
c=
而不运行它,因为它可能由method_missing
处理。 所以整件事实际上是不可判定的。
因为局部变量优先于先前定义的具有相同名称的方法/变量。 在这种情况下,您需要使用’self’进行限定,以便c不被解释为局部变量的声明/赋值。
如果代码不能被解释为变量赋值,Ruby只会调用这种方法。 没有更好的方法来强制方法调用。
self.c = 1 send(:c=, 1) __send__(:c=, 1) method(:c=).call(1) method(:c=)[1]