2016-12-05 44 views
0

此代码区别,如果与外壳之间 - 红宝石

if response != Net::HTTPNoContent 
    raise Exception 
end 
puts "OK" 

打印异常,而该代码

case response 
when Net::HTTPNoContent 
    puts "OK" 
else 
    raise Exception 
end 

打印 “OK” 到控制台。我想知道发生了什么事。 如果您需要更多详细信息,请告诉我。

+0

的'case'语句使用''===内部是由''==不同。 – tadman

回答

2

response变量是,我认为,从使用net/http返回的响应对象。该对象的类型将为Net::HTTPNoContent

在你的第一个变种if,你正在检查,看看你的响应对象等于的Net::HTTPNoContent类。这不会是。 net/http库在发送请求时不会返回类,它将返回一个对象,其中包含有关请求的响应的所有信息(类型为Net::HTTPNoContent或其他类,具体取决于请求的结果)请求)。

然而,在您的case变体中,情况会有所不同。 Ruby试图聪明地处理你给每个when分支的谓词。它会对每个分支做一个三重等于(===)(如#is_a?,在这个例子中,虽然它做了其他事情)比较,如果有问题的对象的类是(或从后裔)到该分支(或者当然,如果对象确实是等于)。

(在Ruby中,类对象了,这就是为什么你可以比较response类本身,就像你if版本,它仍然是有意义的解释。)

所以这是最好的解释通过重写你的if版本:

if !response.is_a?(Net::HTTPNoContent) 
    raise Exception 
end 

puts "OK" 
+0

噢,谢谢。我有时候对ruby的语法有点困惑。非常感谢你。 –

+0

Ruby除了写''除非response.is_a?(...)''。 – tadman

0

简单的例子:

a = 'a' 
if a != String 
    p '-' 
else 
    p '+' 
end 

case a 
when String 
    p '+' 
else 
    p '-' 
end 

返回:

#=> - 
#=> + 

这意味着,在第一个例子中,你尝试检查,如果一些响应的值等于类。当您使用case when String它会检查if a.is_a? String