5

这段代码没有像我预期的那样执行:

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. 顺便说一句,我这样做是因为 a 的输出case可用于变量赋值,而且它比有几个elsif子句更简洁。我希望能够Proc在没有参数的 case 语句中使用任意 s。

4

2 回答 2

7
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

正如 The Pickaxe ( http://pragprog.com/book/ruby3/programming-ruby-1-9 ) 所说,有两种形式的案例陈述。

第一个允许评估一系列条件,执行对应于第一个为真条件的代码: case when ‹ boolean-expression ›+ ‹ then › ...

case 表达式的第二种形式在 case 关键字之后采用目标表达式。‹ 比较 ›+ ‹ then › ... 时的案例目标

在您的情况下(case没有目标),任何不是falsenil(例如 Proc 或字符串 'cat')的表达式都计算为 true。除非您执行,否则不会执行 Proc call

于 2013-01-22T00:07:36.670 回答
5

您可以使用case不带参数的语句来执行类似于if语句的操作。例如:

case
when x > 0 then puts "positive"
else puts "negative"
end

您假设它正在尝试与 进行比较nil,但事实并非如此。相反,当没有参数时,该case语句仅测试“真实”值(除niland之外的任何值false)。因此,当它遇到您的第一条when语句时,它会检查您的Proc(意思是实际的 rubyProc​​ 对象,而不是执行 your 的结果Proc)是nilor false,而不是。由于它是“真实的”,因此该代码将被执行。

试试这个,你会注意到Procnever 甚至被调用/执行(你只会看到"bar",而不是"foo"):

case
when -> { puts 'foo' } then puts 'bar'
else puts "This line will never be printed"
end
于 2013-01-21T23:59:07.713 回答