Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does self.class === MyClass return false, while self.class == MyClass returns true?

Tags:

ruby

I'm using Ruby's case syntax to set up some simple logic based on self.class as follows:

case self.class
 when FirstClass
   do stuff....
 when SecondClass
   do other stuff...
 end

I soon realized this always returns nil. Upon closer investigation, I found that case uses === rather than == to check equality. When running self.class == FirstClass in my terminal I get true as expected, however self.class === FirstClass returns false.

Looking into the ruby docs, I found the following explanation of ===:

Case Equality – For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

Can anyone out there shed some light on what may be happening? Thanks in advance.

like image 748
Zensaburou Avatar asked May 15 '15 20:05

Zensaburou


1 Answers

The clue is in “typically overridden by descendants to provide meaningful semantics in case statements”, in particular Module overrides it:

Case Equality — Returns true if obj is an instance of mod or one of mod’s descendants. Of limited use for modules, but can be used in case statements to classify objects by class.

So for modules === acts very much like the is_a? method (in fact it just calls the same implementing function in MRI Ruby, rb_obj_is_kind_of). In your example it evaluates to false because self.class isn’t an instance of FirstClass. It’s likely to just be an instance of Class. self alone however could be an instance:

case self
when FirstClass
  do stuff....
when SecondClass
  do other stuff...
end

(Although I think your design might not be quite right, testing the class of an object is usually a code smell. Instead you probably should have different implementations of a method in the objects.)

like image 104
matt Avatar answered Nov 14 '22 22:11

matt