内联if条件和块之间的差异如果条件在Ruby中

时间:2014-11-15 06:21:42

标签: ruby block conditional-statements

今天我遇到了Ruby的内联if和奇怪的行为if和阻止if

2.0.0-p247 :001 > inline_if = 'value will not set but no error' if inline_if
 => nil 
2.0.0-p247 :002 > if block_if
2.0.0-p247 :003?>   block_if = 'forget about setting value, I will raise an error'
2.0.0-p247 :004?>   end
NameError: undefined local variable or method `block_if' for main:Object
    from (irb):2
    from /Users/myuser/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'

如果是条件的内联和有条件的阻塞之间有什么区别?

3 个答案:

答案 0 :(得分:2)

我怀疑它与ruby解析器有关。因为在写内联时

inline_if = 'value will not set but no error' if inline_if

Ruby解析器实际上从左到右解析。所以在上面的行中它首先遇到变量inline_if的setter方法。所以它实际上用值nil定义了这个变量,然后检查条件if inline_if,它将被评估为if nil

现在使用阻止条件

if block_if
  block_if = 'forget about setting value, I will raise an error'
end

它首先尝试访问尚未定义的block_if变量。因此它会抛出一个错误。

令人惊讶的是,从程序员的角度来看,上述两个块都应该被平等地评估。但他们表现不同

答案 1 :(得分:2)

请参阅Local Variables and Methods

  

当解析器遇到赋值时创建局部变量,而不是在赋值发生时创建:

a = 0 if false    # does not assign to a
p local_variables # prints [:a]
p a               # prints nil

在第一个示例中,inline_if在赋值时首先遇到,因此创建它(并且值为nil)。在第二个示例中,block_if在分配中看到之前的条件中出现,这会导致错误。

答案 2 :(得分:1)

&#34; Ruby解释器在看到对它的赋值时用nil初始化一个局部变量。&#34;请参阅this answer一个相关的简单问题,该问题突出了您所看到的行为的关键部分。

> a = a
# => nil (and assigns nil to a)
> b = c
# => NameError...

另外,请注意关于JavaScript和Ruby奇怪的这个热闹的video