Ruby 2.2.4 对条件赋值进行词法分析

Ruby 2.2.4 lexing an assignment in a conditional

这两行代码有什么区别?

a = (b if (b = "test"))
a =  b if (b = "test")

第一个运行良好并将 ab 都设置为 test,但第二个抛出错误:

NameError: undefined local variable or method `b' for main:Object

我假设对于第二行,Ruby 会首先计算 b = "test",然后是 if "test",最后是 a = b。到底发生了什么?

(Ruby 版本 2.2.4)

两条线都行不通。两条线都可以工作。这是薛定谔的表达式:)。

您可以 运行 在新的回复中重复两次:

a =  b if b = "test"
#=> NameError: undefined local variable or method `b' for main:Object
a =  b if b = "test"
#=> "test"

让我们看得更深一点,打开一个新的回复:

defined(b)
#=> nil
a = b if b = "test"
#=> NameError: undefined local variable or method `b' for main:Object
defined(b)
#=> local-variable
b
#=> "test"
a = b if b = "test"
#=> "test"

所以实际上 Ruby 已经评估了 b = "test" 部分并在当前范围内定义了这个变量。表达式 a = bif b = "test" 都被执行了。不仅如此,if语句在赋值语句之前执行:

c = p("assignment") && b if b = p("if") && "test"
#=> "if"
#=> "assignment"
#=> NameError: undefined local variable or method `b' for main:Object

但是b变量在第一次求值时没有在赋值语句的范围内定义。在第二种方法中,它已经被定义,所以你收到了正确的结果。

所以,永远不要用这种方式做作业