'case'语句如何与常量一起使用?

时间:2012-10-23 00:37:32

标签: ruby class constants switch-statement

我正在使用Ruby 1.9.2和Ruby on Rails 3.2.2。我有以下方法:

# 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

我想了解为什么在上面的case语句中,当我执行elsemy_method(Article)之类的方法调用时,它始终运行my_method(Comment)“部分”等等。

我该如何解决这个问题?有人有建议如何处理这个吗?

3 个答案:

答案 0 :(得分:4)

这是因为case调用了===,而=== on Class(或者具体是模块,Class从哪个类开始)是这样实现的:

  

mod === objtruefalse

     

案例平等 - 如果trueobj的实例或mod的后代之一,则返回mod。模块的用途有限,但可以在case语句中用于按类对对象进行分类。

这意味着除了Class&之外的任何常数。 Module {例如Foo),Foo === Foo始终返回false。因此,您始终会在else声明中获得case条件。

相反,只需使用对象本身而不是其类调用case,或使用if语句。

答案 1 :(得分:3)

将对象引用传递给方法,就像在后台使用===运算符一样,因此这些将失败。 e.g。

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

另一方面,这很好用:

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

请参阅“如何在Ruby中编写switch语句”https://stackoverflow.com/a/5694333/1092644

的相关答案

答案 2 :(得分:1)

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

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

  ... ...

  end  
end