【问题标题】:Ruby if vs end of the line if behave differently?Ruby if vs end if 行为不同?
【发布时间】:2012-06-13 20:27:12
【问题描述】:

为什么这段代码不起作用?

b if b = true

错误:undefined local variable or method `b'

但这确实:

if b = true
    b
end

他们不应该是一样的吗?

【问题讨论】:

  • 甚至可以简化:k if k = 1if k = 1; k; end
  • 这有点让我烦恼;我不认为你的代码不能工作有什么深层次的原因,所以也许他们会在下一个版本的 ruby​​ 中添加这个功能。
  • 条件是表达式,就像 Ruby 中的其他任何东西一样,所以当解析器正在寻找分配变量时,这种行为是预期的,并且很难改变。我确实同意,但它非常不直观,并且不遵循最小意外原则。
  • 作为编码实践的问题,我宁愿在条件中看不到作业。它使代码的维护变得更加困难,因为很难判断分配是有意的还是发生了拼写错误,它应该是一个相等测试 (==)。它没有按您预期的那样工作这一事实只是在代码审查中标记它的更多理由。

标签: ruby


【解决方案1】:

这是一个很好的问题。它与 Ruby 中变量的作用域有关。

这是一个post by Matz on the Ruby bug tracker 关于这个:

从上到下,从左到右确定局部变量范围。所以在if修饰符的条件下先赋值的局部变量在左侧if体中是无效的。这是一个规范。

【讨论】:

    【解决方案2】:

    在第一个版本中,只要k 被命中,解析器就会呕吐,因为它还没有被看到。

    在第二个版本中,k 是赋值表达式的一部分,并且解析方式不同。

    【讨论】:

      【解决方案3】:

      我不知道原因,但解释器在评估条件之前尝试查找变量 k 的问题。

      如果你这样写,不会有任何错误,按你的预期工作:

      k = nil
      h = {k: 1}
      v = k if k = h.delete(:k)
      

      【讨论】:

        【解决方案4】:

        因为 Ruby 解释器在看到赋值时会创建一个局部变量

        第二种情况,它还没有看到赋值,所以解析表达式时变量不存在。

        更准确地说,一个方法首先被解析成一个内部表示,然后,也许代码最终会被调用并实际执行。

        局部变量在解析过程中创建。这是一个声明的问题,它只是意味着解释器会意识到它们。在有人调用周围的方法之前,它们不会在被赋予空间或值的意义上被创建。

        【讨论】:

          【解决方案5】:

          你只放了一个'='

          试试 '=='

          然后你会得到错误

          在第二个示例中,您将 'true' 分配给 b。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-09-10
            • 2013-08-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多