此代码无法按预期执行:
case
when -> { false } then "why?"
else "This is what I expect"
end
# => "why?"
这也不是
case
when ->(x) {false} then "why?"
else "This is what I expect"
end
# => "why?"
在这两种情况下都会执行第一个then
子句,这必须意味着不会调用我提供给when
子句的lambda。我理解,无论===
子句的主题是什么,都应该调用大小写等于运算符when
。我想知道在===
没有提供参数的情况下,case
的另一边发生了什么。我原以为它可能是nil
,但不能是:
-> {false} === nil
# => ArgumentError: wrong number of arguments (1 for 0)
->(x) {false} === nil
# => false
这会按预期执行,如果正在执行,则会导致我预期的case
结果或异常。有人可以解释上面的结果吗?似乎根本没有使用大小写等于运算符,但第一个when
子句正在评估true
。顺便说一下,我这样做是因为case
的输出可以用于变量赋值,并且它不那么冗长,而是有几个elsif
子句。我希望能够在没有参数的case语句中使用任意Proc
。
答案 0 :(得分:6)
case
when -> { false } then puts "why?"
else puts "This is what I expect"
end
case
when 'cat' then puts "why?"
else puts "This is what I expect"
end
case
when -> { false }.call then puts "why?"
else puts "This is what I expect"
end
输出:
why?
why?
This is what I expect
正如镐(http://pragprog.com/book/ruby3/programming-ruby-1-9)所说,有两种形式的案例陈述。
第一个允许评估一系列条件,执行 对应于第一个条件为真的代码:< boolean-expression> +
... 案例表达式的第二种形式采用目标表达式 关注case关键字。 <比较> + <然后>时的案例目标 ...
在您的情况下(case
没有目标)任何非false
或nil
的表达式(例如Proc或字符串'cat')的计算结果为true。除非call
,否则不执行Proc。
答案 1 :(得分:5)
您可以使用不带参数的case
语句来执行与if
语句类似的操作。例如:
case
when x > 0 then puts "positive"
else puts "negative"
end
你假设它正在尝试与nil
进行比较,但事实并非如此。相反,当没有参数时,case
语句仅测试“truthy”值(除nil
和false
之外的任何值)。因此,当它达到您的第一个when
语句时,它会检查您的Proc
(表示实际的红宝石Proc
对象,不执行您的{{ {1}})Proc
或nil
,而不是false
。由于它是“真实的”,该代码被执行。
试试这个,你会注意到Proc
甚至从未被调用/执行过(你只会看到"bar"
,而不是"foo"
):
case
when -> { puts 'foo' } then puts 'bar'
else puts "This line will never be printed"
end