2010-10-11 101 views
96

是什麼沒有這些作品有時的第一個和第二Ruby類類型和case語句

case item.class 
when MyClass 
    # do something here 
when Array 
    # do something different here 
when String 
    # do a third thing 
end 

case item.class 
when MyClass.class 
    # do something here 
when Array.class 
    # do something different here 
when String.class 
    # do a third thing 
end 

之間的區別出於某種原因,和其他時間,第二個工作,第一個不工作。爲什麼?哪一種是「正確」的方式?

+1

字符串是一類。一個類的類是Class。 – Volte 2015-09-30 08:35:36

回答

167

您必須使用:

case item 
    when MyClass 

我有同樣的問題: How to catch Errno::ECONNRESET class in "case when"?

+1

謝謝!很抱歉欺騙(或類似欺騙),但幾次搜索沒有出現以前的問題。似乎案例陳述對===的使用是一個相當普遍的問題,現在我發現這是問題所在。這應該在教程和其他教程中更頻繁地指出(但我敢打賭,很多教程作者都沒有意識到這一點)。 – 2010-10-13 13:28:08

+2

如果使用ActiveRecord,還沒有提到一個警告。類比較的ActiveRecord ===方法使用.is_a?,這意味着在case語句中類的子類將評估爲true。 https://github.com/rails/rails/blob/04cda1848cb847c2bdad0bfc12160dc8d5547775/activerecord/lib/active_record/core.rb#L135 – 2014-02-07 23:48:50

1

這取決於item變量的性質。如果它是一個對象的實例,例如

t = 5 

然後

t.class == Fixnum 

但如果是在本身的一類e.g

t = Array 

那麼這將是一個Class對象,所以

t.class == Class 

EDIT:請參閱How to catch Errno::ECONNRESET class in "case when"?正如Nakilon所述,因爲我的回答可能是錯誤的。

+2

'case'使用'===' – Nakilon 2010-10-11 17:12:26

+0

在Ruby中,一切都是「對象的一個​​實例」。 – 2017-04-03 15:48:52

4

在Ruby中,類名是指Class類型的對象,描述一個特定類的常數。這意味着在Ruby中使用MyClass等同於在Java中使用MyClass.class

obj.classClass類型的對象,其描述了obj的類別。如果obj.classMyClass,則使用MyClass.new(粗略地講)創建objMyClass是描述使用MyClass.new創建的任何對象的Class類型的對象。

MyClass.class是類的對象MyClass的(這是Class類型的對象,描述了使用MyClass.new創建的任何對象的類)。換句話說,MyClass.class == Class

45

是的,Nakilon是正確的,你必須知道3qual ===運算符如何處理when子句中給出的對象。在Ruby

case item 
when MyClass 
... 
when Array 
... 
when String 
... 

真的

if MyClass === item 
... 
elsif Array === item 
... 
elsif String === item 
... 

瞭解這種情況下被調用threequal方法(MyClass.===(item)爲例),並且可以定義方法做任何你想要的,那麼你可以使用與precisionw

case語句
+0

如果我有'arr = []',那麼我注意到'如果Array === arr'會評估爲true,但是'如果arr === Array'將評估爲false。有人可以幫忙解釋嗎? – Daniel 2013-03-21 10:30:21

+4

===只是一個可以定義的方法,可以做任何類的設計者希望它做的事情。請記住,另外,a === b實際上意味着a。=== b,所以如果切換a和b,您可能會得到不同的行爲。不能保證===是可交換的。實際上,Array === Array是false,但Object === Object是true,所以Array重新定義了===的語義。 – Fred 2013-03-21 22:58:18