2012-11-09 51 views
1

兩個類似的腳本在這裏顯示非常奇怪的行爲。下面具有真值的案例陳述

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到控制檯上。我錯了嗎?爲什麼?

回答

5

當給出參數時,case語句檢查對象是否相等(與調用===相同),可以使用單個值或超出範圍。在你的情況,你沒有真正檢查平等,但它可以這樣寫:

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

然而,這是你想要做的(一個非此即彼/或條件)什麼很詳細。這是簡單的使用普通if...else或三元聲明:

score += amount >= 3 ? 10 : 1 
+0

哦,所以它的所有有關的說法!感謝您的快速回答。 PS .:順便說一下,這個例子被簡化以便開始對話,真正的更大。 –

0

您應該使用「那麼」而不是「;」在案件內部並且不爲案件申明ammount變量,只要使用你在那裏的條款。 更容易使用三元操作有你想要的結果:

score += ammount >= 3 ? 10 : 1 
+0

這正是@ZachKemp所說的。 –

+0

當然,但在這種情況下,我對分數變量有其他選擇。我的例子很簡單。 –

+0

@MarkThomas提交後看到它...必須提交大約在同一時間.. – matov

1

你混合兩種情況下聲明:

  1. case variable 
    when range/expression then ... 
    else statement 
    end 
    
  2. case 
    when case1 then ... 
    else ... 
    end 
    

問題:

爲什麼你的代碼不起作用?

答:

當您在case指定變量,一個隱含的===操作將被應用到每個when測試。在你的情況下,amount是4,並且它大於3,那麼amount> = 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