解析与操作的可变范围和顺序:"if"中的赋值

baa*_*h05 4 ruby variable-assignment conditional-statements

我的理解是,if行前面的语句在行前面的代码之前进行了评估:

'never shown' if (false)
Run Code Online (Sandbox Code Playgroud)

并且可以在if声明中进行分配.

'shown' if (value = 'dave is king')
value #=> "dave is king"
Run Code Online (Sandbox Code Playgroud)

并且,当分配不存在的变量时,将创建该变量.事先不需要它存在.这是真的?

如果所有这些假设都成立,为什么会失败呢?

error_array << error if (error = import_value(value))
#=> undefined local variable or method `error' for
Run Code Online (Sandbox Code Playgroud)

它在数组推右前分配给错误?我想了解什么时候进行评估.

这个确实有效:

if (error = import_value(value))
  error_array << error
end
Run Code Online (Sandbox Code Playgroud)

现在我真的很困惑.

Clu*_*ter 5

它只会在您尝试分配文字值时发生,如果您调用它起作用的函数.

def foo(a)
  a
end

p 'not shown' if(value = foo(false))
p 'shown' if(value = foo(true))

# This outputs a Warning in IRB
p 'shown' if(value = false)
(irb):2: warning: found = in conditional, should be ==
Run Code Online (Sandbox Code Playgroud)

如果打开调试(-d),您将看到有关已使用变量的警告 value

warning: assigned but unused variable - value
Run Code Online (Sandbox Code Playgroud)

这"有效",因为该语句确实进行了评估true,并允许其前面的代码运行.

这里发生的是if()当用作修饰符时它有自己的绑定范围或上下文.因此,在if之外永远不会看到赋值,因此执行起来没有任何意义.这与控制结构不同,因为if语句所采用的块也与赋值在同一范围内,而if修饰符之前的行不在if的范围内.

换句话说,这些并不等同.

if a = some(value)
  puts a
end

puts a if(a = some(value))
Run Code Online (Sandbox Code Playgroud)

前者具有puts aif puts a的范围,后者具有范围之外,因此具有不同的绑定(ruby称之为上下文).

Ruby运营顺序