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

我正在使用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语句中,当我执行my_method(Article)my_method(Comment)等方法调用时,它始终运行else “part”。

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


这是因为case调用====== (或特定模块,类是从哪里下来的)实现如下:

mod === objtruefalse

Case Equality - 如果objmod的实例或mod的后代之一,则返回true 。 模块的用途有限,但可用于case语句以按类别对对象进行分类。

这意味着对于除了ClassModule (例如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语句”的相关答案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/25645.html

上一篇: How does the 'case' statement work with constants?

下一篇: else structure in Ruby