x == User
会返回true
,但case x
语句不会运行与User
关联的块。这里发生了什么?
u = User.new
# => #<User:0x00000100a1e948>
x = u.class
# => User
x == User
# => true
case x
when User
puts "constant"
when "User"
puts "string"
else
puts "nothing?"
end
# => nothing?
答案 0 :(得分:21)
案例比较使用===
而不是==
。对于许多对象,===
和==
的行为相同,请参阅Numeric
和String
:
5 == 5 #=> true
5 === 5 #=> true
"hello" == "hello" #=> true
"hello" === "hello" #=> true
但是对于其他类型的对象===
可能意味着许多事情,完全取决于接收者。
对于类的情况,===
测试对象是否是该类的实例:
Class === Class.new #=> true.
对于Range,它会检查对象是否属于该范围:
(5..10) === 6 #=> true
对于Procs,===
实际上调用了Proc
:
multiple_of_10 = proc { |n| (n % 10) == 0 }
multiple_of_10 === 20 #=> true (equivalent to multiple_of_10.call(20))
对于其他对象,请检查其===
的定义以揭示其行为。它并不总是很明显,但它们通常会产生某种意义..
以下是将所有内容放在一起的示例:
case number
when 1
puts "One"
when 2..9
puts "Between two and nine"
when multiple_of_10
puts "A multiple of ten"
when String
puts "Not a number"
end
有关详细信息,请参阅此链接:http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/
答案 1 :(得分:2)
在case语句中,使用===
运算符进行比较。
所以你的代码被翻译成以下内容:
case x
when User === x
puts "Constant"
when "User" === x
puts "string"
else
puts "nothing"
end
不同的类以不同的方式定义===
:
Class
类定义===
,以便它测试右手操作数(x
)是否是左手操作数(User
)命名的类的实例。因此,将User === x
评估为false
并不奇怪。相反,User === u
(u = User.new)为true
。
irb(main):001:0> class User
irb(main):002:1> end
=> nil
irb(main):003:0> u = User.new
=> #<User:0xb7a90cd8>
irb(main):004:0> User === u.class
=> false
irb(main):005:0> User === u
=> true