多条件评估

Mik*_*e W 2 ruby

我有一个快速的问题 :

在红宝石中,如果我写

def test
  foo && a  == b && c == "bar"
end
Run Code Online (Sandbox Code Playgroud)

如果 foo 为 null 或 false,它会继续评估表达式的其余部分吗?

如果我这样做,它会改变什么吗

def test
  a == b && c == "bar" if foo
end
Run Code Online (Sandbox Code Playgroud)

多谢

Eri*_*nil 5

理论

&&是一个惰性运算符,就像||.

这意味着在a && b, 如果a为 false 或 nil ,Ruby 不会费心检查,b因为a && b无论如何都会是 false/nil。

这种行为实际上是需要的,因为它可以节省时间并且可以避免 NoMethodErrors。

if a && method_which_requires_a_non_nil_parameter(a)
  # ...
end
Run Code Online (Sandbox Code Playgroud)

method_which_requires_a_non_nil_parameter如果a为零,则根本不会被调用。

或者 :

x = x || long_method_to_calculate_x
Run Code Online (Sandbox Code Playgroud)

常用于缓存,更常写为:

@x ||= long_method_to_calculate_x
Run Code Online (Sandbox Code Playgroud)

回答

def test
  foo && a  == b && c == "bar"
end
Run Code Online (Sandbox Code Playgroud)

如果 foo 为 nil 或 false ,则不会评估表达式的其余部分:a、b、c 甚至可能未定义而不会引发 NameError。

def test
  a == b & c == "bar" if foo
end
Run Code Online (Sandbox Code Playgroud)
  • 如果 foo 为真,结果将完全相同。

  • 如果 foo 为 nil 或 false,则不会评估 2 个等式,就像第一个示例一样。但 :

    • 如果 foo 为 nil,则两个测试都将返回 nil。

    • 如果 foo 为 false,第一个示例将返回 false,第二个示例将返回 nil。