【问题标题】:Ruby 2.2.4 lexing an assignment in a conditionalRuby 2.2.4 对条件中的赋值进行词法分析
【发布时间】:2016-07-20 05:01:00
【问题描述】:

这两行代码有什么区别?

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)

【问题讨论】:

  • 这些都不能在 ruby​​ 2.3 中工作(就像它应该的那样)。
  • 德文郡,您可以检查instruction sequences 的两条线并自己找出差异。我个人不会打扰,因为这段代码永远不应该被使用,而且无论如何它不会在最新的 ruby​​ 中重现。
  • 无法复制。

标签: ruby conditional lexical-analysis operator-precedence


【解决方案1】:

两条线都行不通。两条线都行。这是薛定谔表达式:)。

你可以在一个新的 repl 中运行两次:

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

让我们深入看看,打开一个新的repl:

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 变量在第一次评估时未在赋值语句的范围内定义。而在第二种方法中,它已经被定义,所以你收到了正确的结果。

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

【讨论】:

  • 啊,repl 可能是答案,是的。 :)
  • 所以看起来当我测试这个问题时,我遇到了一个不幸的情况,它总是以一种方式工作,而不是另一种方式,作为订购的巧合。谢谢!
猜你喜欢
  • 2019-06-03
  • 2011-02-25
  • 2014-07-26
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 2018-07-21
相关资源
最近更新 更多