为什么在这个单行条件中对赋值的处理方式不同?

时间:2011-08-12 06:16:01

标签: ruby statement-modifiers

我已经阅读了一些内容,包括thisthis,但我认为以下示例与他们所讨论的内容不同。实际上,一个人在讨论中提出了一个类似的例子,但它被忽略了。

因此,在irb中运行(忽略有条件的赋值警告):

(puts x) if (x = 0) # NameError: undefined local variable or method `x'...
x                   # => 0
(puts x) if (x = 0) # "0", => nil

但第二次没有错误。

这是否有意义,即使在“一旦你理解了解析器真正在做什么,这只是一些优化,这一切都变得清晰”的方式?因为对我来说,这看起来很不可取。

要明确的是,上述条件应该等同于(对吗?)

if newvar=0
  puts newvar
end

不会引发错误。


更新:自从提出这个问题以来,关于此主题的帖子甚至更多。例如,
http://seejohncode.com/2012/07/31/ruby-gotcha-single-line-conditionals/

4 个答案:

答案 0 :(得分:1)

奇怪的是,这在Rubinius中运作良好:

Welcome to IRB. You are using rubinius 1.2.4dev (1.8.7 7ae451a1 yyyy-mm-dd JI)
>> (puts x) if (x = 0) #=> nil
0

我倾向于说它是MRI中一个奇怪的解析错误。

答案 1 :(得分:1)

我认为这种情况的不同之处在于变量在解析行时是否存在。在以下情况下:

if x=0
  puts x
end

变量x在解析使用x的行之前定义。

换句话说,错误消息是解析时错误,而不是运行时错误。

答案 2 :(得分:0)

我认为你在这里分配0到x。

(puts x) if (x = 0)

我认为应该是

(puts x) if (x == 0)

答案 3 :(得分:0)

首先,在条件子句中检查您的意思是x=0

其次,puts x if x = 0不等同于:

if x = 0
  puts x
end

在您的情况下,puts x尚未声明x,因此无法看到它。