'case'语句如何处理常量?



我使用的是Ruby 1.9.2,Ruby在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语句中,当我执行诸如my_method(Article)my_method(Comment)等方法时,它总是运行else" part"。

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

这是因为case调用===,而===在类上(或专门的模块,class discends frocs so so:

mod === objtruefalse

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

这意味着除了Class&Module(例如Foo),Foo === Foo始终返回false。结果,您始终在case语句中获得else条件。

而不是将对象本身而不是类别调用case,或者使用if语句。

将对象引用传递到该方法,如背景中,它使用===操作员,因此这些将失败。例如

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语句"的相关答案。

如果您只想比较名称的平等,则可以将to_s添加到类常数。

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

最新更新