为什么这种情况不能正常工作?

时间:2015-05-31 07:16:05

标签: ruby case

  if ( item::class == RPG::Weapon )
    print "yup"
  end
  case item::class
  when RPG::Item
    type = 0
  when RPG::Weapon
    type = 1
  when RPG::Armor
    type = 2
  else
    type = 10
  end

我是Ruby的新手。 if语句运行正常并打印“是”,但case语句不能正常工作并将类型设置为10.我是否对某些事情视而不见?

2 个答案:

答案 0 :(得分:2)

Module#===测试参数是否为self的实例。除了Class之外,item.class永远不会是任何事件的实例,特别是,它永远不会是RPG::WeaponRPG::Armor的实例,因此when都不会} branches将永远匹配,您将始终获得else分支。

顺便说一句:使用名称空间解析运算符::进行邮件发送而不是邮件发送运算符. 非常非惯用且令人困惑(并且赢了&#39 ; t适用于名称以大写字符开头的方法。事实上,我相信matz认为这个功能在Ruby中添加了一个错误。

另请注意,case是一个表达式,事实上,Ruby中的所有都是表达式。

我会按如下方式编写代码:

type = case item
  when RPG::Item
    0
  when RPG::Weapon
    1
  when RPG::Armor
    2
  else
    10
end

然而,一般来说,条件是代码气味。 Ruby是一种面向对象的语言,多态性(即基于self类型的方法调度)是all the conditional you need!实际上,在这个例子中,您是手动检查item的类以确定其类型,但完全无论如何,调度的方法是什么!就个人而言,我会refactor这样的代码:

class RPG::Item
  def type
    0
  end
end

class RPG::Weapon
  def type
    1
  end
end

class RPG::Armor
  def type
    2
  end
end

class RPG::Object # or whatever your baseclass is
  def type
    10
  end
end

现在,当您添加新类型的游戏对象时,您不必通过向case表达式添加新分支来修改现有代码。您只需添加新类,无需修改任何现有代码。

答案 1 :(得分:0)

只需case item即可 - 无需case item::class

Ruby中的案例匹配是通过模糊匹配(===)算法完成的,该算法并不需要这样的特定条款。