2010-10-11 93 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