【问题标题】:Why in Ruby, a || 1 will throw an error when `a` is undefined, but a = a || 1 will not?为什么在 Ruby 中,一个 || 1 当 `a` 未定义时会抛出错误,但是 a = a || 1不会?
【发布时间】:2010-06-06 06:54:50
【问题描述】:

a 未定义时,a || 1 会抛出错误,但a = a || 1 不会。是不是有点不协调?

irb(main):001:0> a
NameError: undefined local variable or method 'a' for main:Object
        from (irb):1
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):002:0> a || 1
NameError: undefined local variable or method 'a' for main:Object
        from (irb):2
        from c:/ruby/bin/irb:12:in '<main>'

irb(main):003:0> a = a || 1
=> 1

【问题讨论】:

标签: ruby exception undefined undefined-behavior


【解决方案1】:
a

在这里,您正在评估未定义的 a。因此,您会遇到异常。

a || 1

在这里,您仍然必须评估a 以确定布尔表达式的值。就像上面一样,a 没有定义。因此,您会遇到异常。

a = a || 1

在这里,a 定义。它被定义为未初始化的局部变量。在 Ruby 中,未初始化变量的计算结果为 nil,因此赋值表达式的右侧计算结果为 nil || 1,其计算结果为 1,因此赋值表达式的返回值为 1,副作用是a 被初始化为 1

编辑:在 Ruby 中何时定义变量以及何时初始化变量似乎存在一些混淆。 get 在解析时定义,但在运行时初始化。你可以在这里看到它:

 foo # => NameError: undefined local variable or method `foo' for main:Object

foo 未定义。

if false
  foo = 'This will never get executed'
end

此时,foo 已定义,即使该行永远不会被执行。该行永远不会被执行的事实完全无关紧要,因为无论如何解释器都与此无关:局部变量是由解析器定义的,而解析器显然会看到这一行。

foo # => nil

没有错误,因为 foo 已定义,它的计算结果为 nil,因为它未初始化。

【讨论】:

  • +1,虽然我认为“它被定义为未初始化的局部变量”。有点混乱。当您执行var = expr 时,您并没有将var 定义为未初始化。您将 var 定义为 expr 的值。只是在expr 求值时,var 恰好未初始化,这意味着在expr 中对var 的任何引用都将求值为nil。
  • @sepp2k:它们是两个非常独立的步骤。变量定义发生在解析器中,初始化发生在解释器中。根据 Ruby 实现,这两个事件之间可能会有很长的时间。例如,在 BlueRuby 中,当您安装 Ruby 程序时,Ruby 源代码被解析为 BRIL(BlueRuby 中间语言),然后存储在数据库中。在有人真正运行该程序之前,可能需要 。一直以来,变量已定义但未初始化。这两件事甚至可能发生在不同的机器上。
【解决方案2】:

当您执行a || 1 时,您要求它查找未定义的a 的值。

当您执行a = a || 1 时,您要求它查找将a 分配给a 的值,这似乎不会出错。

所以,虽然很奇怪,但我不认为它不一致。

【讨论】:

  • 这是错误的。 a = a || 1 不会解析为 (a = a) || 1。它解析为a = (a || 1),因此“将a分配给a”的结果与它无关,因为a从未分配给a。
  • @sepp2k:我根本不想暗示这一点。如果我让你感到困惑,我很抱歉。我相信 Jörg 已经解释的更清楚了。
【解决方案3】:

这是你的意思吗?

if !(defined? a) then
    a = 1
end

将值声明为默认值可能更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多