How does the 'case' statement work with constants?

I am using Ruby 1.9.2 and Ruby on Rails 3.2.2. I have the following method:

# Note: The 'class_name' parameter is a constant; that is, it is a model class name.
def my_method(class_name)
  case class_name
  when Article then make_a_thing
  when Comment then make_another_thing
  when ...     then ...     
  else raise("Wrong #{class_name}!")
  end  
end

I would like to understand why, in the case statement above, it always runs the else "part" when I execute method calls like my_method(Article) , my_method(Comment) and so on.

How can I solve the issue? Does someone have advice how to handle this?


This is because case calls === , and === on Class (or specifically Module, which Class descends from) is implemented like so:

mod === objtrue or false

Case Equality—Returns true if obj is an instance of mod or one of mod 's descendants. Of limited use for modules, but can be used in case statements to classify objects by class.

This means that for any constant except Class & Module (eg Foo ), Foo === Foo always returns false . As a result, you always get the else condition in your case statement.

Instead just call case with the object itself, instead of its class, or use if statements.


Pass an object reference to the method, as in the background it uses the === operator, so these will fail. eg

obj = 'hello'
case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

This on the other hand, works fine:

obj = 'hello'
case obj  # was case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

See a relevant answer to "How to write a switch statement in Ruby" https://stackoverflow.com/a/5694333/1092644


如果您只想比较名称的相等性,可以将to_s添加到类常量中。

def my_method(class_name)
  case class_name.to_s
  when 'Article'
    make_a_thing
  when 'Comment'
    make_another_thing

  ... ...

  end  
end
链接地址: http://www.djcxy.com/p/25646.html

上一篇: 如何更改散列键

下一篇: 'case'语句如何与常量一起工作?