2015-09-07 36 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的回答。 –

相关问题