问题
x == User returns true, but case x statement does not run the block associated with User. What's happening here?
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?
回答1:
Case comparisons use === rather than ==. For many objects the behaviour of === and == is the same, see Numeric and String:
5 == 5 #=> true
5 === 5 #=> true
"hello" == "hello" #=> true
"hello" === "hello" #=> true
But for other kinds of object === can mean many things, entirely depending on the receiver.
For the case of classes, === tests whether an object is an instance of that class:
Class === Class.new #=> true.
For Range it checks whether an object falls in that range:
(5..10) === 6 #=> true
For Procs, === actually invokes that Proc:
multiple_of_10 = proc { |n| (n % 10) == 0 }
multiple_of_10 === 20 #=> true (equivalent to multiple_of_10.call(20))
For other objects, check their definition of === to uncover their behaviour. It's not always obvious, but they usually make some kind of sense..
Here is an example putting it all together:
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
See this link for more info: http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/
回答2:
In case statement , the comparison is done using === operator.
So your code is translated to following:
case x
when User === x
puts "Constant"
when "User" === x
puts "string"
else
puts "nothing"
end
Different class define === in different way:
The Class class define === so that it tests whether the righthand operand (x)is an instance of the class named by the lefthand operand (User). So , It is not surprise that User === x will be evaluated as false. Instead, User === u (u = User.new) is 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
来源:https://stackoverflow.com/questions/3757818/ruby-when-keyword-does-not-use-in-case-statement-what-does-it-use