2015-09-07 53 views
1

使用case/when語句用於檢查一個實例的類會失敗。如果我比較的Answer實例的類,如下所示,它失敗:類Case語句失敗,轉換爲字符串成功

subject = Answer.new 
case subject.class 
when Answer 
    true 
else 
    false 
end 
# => false 

如果我轉換的Answer實例的類的字符串,它的工作原理:

subject = Answer.new 
case subject.class.to_s 
when 'Answer' 
    true 
else 
    false 
end 
# => true 

這不是怎麼它應該是,對?此外,當我運行一個簡單的比較,它的工作原理:

subject.class == Answer 
# => true 

編輯:使用Ruby的case===的新特性瞭解到,這個代碼是有效的和作品。

subject = Answer.new 
case subject 
when Answer 
    true 
else 
    false 
end 
# => true 
+2

Ruby'case'語句基於'==='運算符。 Google搜索「ruby triple equal case statement」,你會發現一些有趣的信息來解釋你的結果。 – lurker

回答

1

Ruby中case是基於===操作。當你有:

case x 
when foo 
... 
when bar 
... 
end 

它的行爲是:

if foo === x 
    ... 
elsif bar === x 
    ... 
end 

在一般意義上,a === b意味着b屬於或者是由什麼a代表納入。見所定義的here

案例平等 - 返回true,如果obj爲或國防部的一個實例 國防部的後裔之一。模塊的使用受到限制,但可用於 語句以按類別對對象進行分類。

例如,(2..7) === 3爲真,因爲3包含在範圍內,2..7。基於對象如何界定===,這也是事實,2 === 2由於2屬於類的2。它是不是交換運算符(例如,a === b的真實值並不意味着b === a爲真)。諸如Integer === 3之類的表達式是true,因爲3Integer。但3 === Integer因爲3不代表或包含Integer的整個類別而不是真的。所以===運算符使Ruby case語句做了一些強大而有用的匹配。

在這個特定的case聲明中,您檢查Answer === subject.class是否爲true。由於subject.class不屬於Answer的類,因此未在類對象上定義運算符===以使其成爲true。然而,s.class == Answertrue,因爲s.class確實是Answer。所以案件不符。但是,Answer === s爲真,因爲sAnswer的一種。

+0

通過指向文檔的鏈接和其中的摘錄增強您的答案(http://ruby-doc.org/core-2.2.0/Module.html#method-i-3D-3D-3D) –

+0

@SergioTulentsev感謝鏈接。我會那樣做的。 – lurker

+0

不知道'==='。但是,如果沒有'case'語句,那麼不是編譯成'foo === x',而是編譯爲'x === foo'(據我所知,這會使它成爲我的用法)?還是有'case'的高級用法考慮了'==='的細節? –

1

Answer返回泛型類定義。
Answer.new.class返回實際實例的散列。

> Answer 
=> Answer(id: integer, created_at: datetime, updated_at: datetime) 
> Answer.new 
=> #<Answer id: nil, created_at: nil, updated_at: nil> 

注意#和不同的格式。

由於潛伏者在他的回答好心指出,case使用===運營商,而不是==

利用這些信息,你可以重寫你的case語句這樣

> subject = Answer.new 
> case subject  
?> when Answer 
?> true 
?> else 
?>  false 
?> end 
=> true 

以上case翻譯爲 「不subject屬於Answer?」。答案是肯定的,因爲subjectAnswer的一個實例。

+0

雖然這與字符串方法相同,不是嗎?我的意思是,Answer實例的'.class'方法仍然返回'Answer'(請參閱我的問題的最後一個代碼塊),'case'語句除外。我可以使用這些名稱,但我覺得應該不需要檢查一個班是否是班。 –

+0

對不起,但在我的問題的最後一個代碼塊中,Ruby確認'subject.class == Answer'是真的 - 那麼爲什麼它在條件中是真的,而不是在'case'語句中應該檢查相同的條件? –

+0

@KristapsA .:「應該檢查相同的條件」 - 這是一個錯誤的期望。 'case/when'不是'if/=='的簡單替換。這是一個完全不同的野獸。請參閱@ lurker的回答。 –

相關問題