具有真值的案例陈述

时间:2012-11-09 23:03:04

标签: ruby typeerror

两个类似的脚本在这里显示出非常奇怪的行为。

A)以下代码抛出nil can't be coerced into Fixnum (TypeError)

    score = 0
    ammount = 4

    score += case ammount
      when ammount >= 3; 10
      when ammount < 3; 1
    end

    puts score

B)另一个是将1放入控制台日志。

    score = 0
    ammount = 4

    score += case ammount
      when ammount >= 3; 10
      else 1
    end

    puts score

我希望两个脚本都能将10输出到控制台上。我错了吗?为什么呢?

3 个答案:

答案 0 :(得分:5)

当给出一个参数时,case语句检查对象是否相等(与调用===相同),它可以与单个值或超出范围一起使用。在你的情况下,你并没有真正检查是否相等,但可以这样写:

score += case
         when amount >= 3 then 10
         when amount < 3 then 1
         end

然而,对于你想要做的事情(一种或两种情况)来说,这是非常冗长的。使用普通if...else或三元语句更简单:

score += amount >= 3 ? 10 : 1

答案 1 :(得分:1)

您正在混合两种类型的案例陈述:

  1. case variable
    when range/expression then ...
    else statement
    end
    
  2. case
    when case1 then ...
    else ...
    end
    
  3. <强>问题:

    为什么你的代码不起作用?

    <强>答案:

    case中指定变量时,隐式===操作将应用于每个when测试。在您的情况下,amount为4,且大于3,则数量&gt; = 3为true,因此第一次测试时是amount === true。显然它不是,所以它会转到下一个,下一个是false并且它也不是假的,因此case语句将返回nil,然后你会收到错误nil class cannot be coerced

    第二种情况也一样。

    正确的解决方案是使用上述之一:

    或者:

    score = 0
    ammount = 4
    
    score += case
      when ammount >= 3; 10
      when ammount < 3; 1
    end
    

    或:

    score = 0
    ammount = 4
    
    score += case ammount
      when 3..(1.0/0.0); 10
      when -(1.0/0.0)...3; 1
    end
    

答案 2 :(得分:0)

你应该使用'then'代替';'在案例中并且没有声明案例的ammount变量,只需使用你在那里的子句。 使用三元操作更容易获得您想要的结果:

score += ammount >= 3 ? 10 : 1