你似乎理解错case的用法了。case使用的是===做判断,而非==。要理解清楚这个问题,你首先需要知道“===”只是个“方法”。对于不同的类,它们对===有了不同的定义,也就会有不同的行为。对于普通对象(Object)来说 === 就是 == (请参见http://ruby-doc.org/core-1.9.3/Object.html )而对于Module,这个操作符被重载了。它的行为有点不一样。我还是来具体说一下吧。
obj === other → true or false
Case Equality—For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.
我简单翻译一下:
obj === other 返回true或者false
用于case语句时的比较,对于Object类来说,===的行为和==是一致的,但这个通常被子类(后裔)覆盖,以便在case语句中提供更有意义的语义。
这里面提到了===会被重载的问题,实际上,Module类就覆盖了===这个方法。在Module类里面,===用于判断指定参数是否为mod的后裔(有点像kind_of?方法)换句话说:
1 === Fixnum
#=>false 1是Object而非Module, ===等同于==,而1显然不是Fixnum
Fixnum === 1
#=> true Fixnum是Class也是Module,1是Fixnum的实例,也就是Fixnum的后裔。
RPG::Weapon === RPG::Weapon
#=> false RPG::Weapon 不是 RPG::Weapon的实例及后裔!
1 === Fixnum
#=>false 1是Object而非Module, ===等同于==,而1显然不是Fixnum
Fixnum === 1
#=> true Fixnum是Class也是Module,1是Fixnum的实例,也就是Fixnum的后裔。
RPG::Weapon === RPG::Weapon
#=> false RPG::Weapon 不是 RPG::Weapon的实例及后裔!
其实你可以这样,涉及到类的时候你 cls/mod == obj 想做: obj.kind_of? cls/mod就可以了。
Class === Class
#=> true
#等效于Class.kind_of? Class
Class .ancestors
#=> [Class, Module, Object, Kernel, BasicObject]
#我们看下Class的继承关系,也就是它的祖先
Object == Class
#=>true
#等效于Class.kind_of? Object
# 因为我们观察到Object是Class的祖先,所以这个是成立的
#
Class === Class
#=> true
#等效于Class.kind_of? Class
Class .ancestors
#=> [Class, Module, Object, Kernel, BasicObject]
#我们看下Class的继承关系,也就是它的祖先
Object == Class
#=>true
#等效于Class.kind_of? Object
# 因为我们观察到Object是Class的祖先,所以这个是成立的
#