# Case not calling class' '===' method?

**URL:** <https://rubytalk.org/t/case-not-calling-class-method/5368>\
**Category:** ruby-talk\
**Created:** [27 March 2003 04:11 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368 "2003-03-27T04:11:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ptkwt1](https://avatars.discourse-cdn.com/v4/letter/p/85e7bf/32.png) [@Ptkwt1](https://rubytalk.org/u/Ptkwt1)\
**Post date:** [27 March 2003 04:11 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/1 "2003-03-27T04:11:24Z")

</div>

maybe I’m missing something obvious…

I’ve defined a ‘===’ operator for my class, but it doesn’t seem to get  
called by case. Here’s the code:

class StateType  
attr\_accessor :state  
def initialize(\*states)  
@states = states  
@state = states[0]  
end

def ===(state)  
puts “StateType::===”  
@state == state  
end

def assign(state)  
raise “Not a valid state: #{state}” unless @states.include? state  
@state = state  
end

def \<\<(state)  
assign(state)  
end

end

def what(s)  
case s  
when :start  
"START"  
when :wash  
"WASH"  
when :rinse  
"RINSE"  
when :spin  
"SPIN"  
when :stop  
"STOP"  
else  
"DUNNO"  
end  
end

#this returns true:  
fsmt === :start #=\> prints “StateType::===”

what(fsmt)  
#=\> returns “DUNNO”

(and “StateType::===” is not printed)

What gives?

Phil

---

<div class="post-metadata">

**Author:** ![Tim\_Bates](https://avatars.discourse-cdn.com/v4/letter/t/3da27b/32.png) [@Tim\_Bates](https://rubytalk.org/u/Tim_Bates)\
**Post date:** [27 March 2003 04:22 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/2 "2003-03-27T04:22:54Z")

</div>

Case uses the === operator the opposite way around to what you might expect.

irb(main):001:0\> “myString” === /my/  
false  
irb(main):002:0\> /my/ === “myString”  
0  
irb(main):003:0\> case “myString”  
irb(main):004:1\> when /my/  
irb(main):005:1\> true  
irb(main):006:1\> end  
true  
irb(main):007:0\> case /my/  
irb(main):008:1\> when “myString”  
irb(main):009:1\> true  
irb(main):010:1\> end  
nil

In the example of  
case “myString”  
when /my/  
true  
end  
Ruby actually calls Regexp#===, not String#===

Tim Bates

> **···**
>
> On Thu, 27 Mar 2003 2:41 pm, Phil Tomson wrote:
> 
> > maybe I’m missing something obvious…
> 
> –  
> tim@bates.id.au

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [27 March 2003 04:32 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/3 "2003-03-27T04:32:14Z")

</div>

Hi,

> maybe I’m missing something obvious…
> 
> I’ve defined a ‘===’ operator for my class, but it doesn’t seem to get  
> called by case. Here’s the code:

In a code like

case a  
when b  
…  
end

“===” is called like “b === a”, not “a === b”. I hope this explains  
what happened on your code.

```
						matz.

```

> **···**
>
> In message “case not calling class’ ‘===’ method?” on 03/03/27, Phil Tomson [ptkwt@shell1.aracnet.com](mailto:ptkwt@shell1.aracnet.com) writes:

---

<div class="post-metadata">

**Author:** ![Ptkwt1](https://avatars.discourse-cdn.com/v4/letter/p/85e7bf/32.png) [@Ptkwt1](https://rubytalk.org/u/Ptkwt1)\
**Post date:** [27 March 2003 05:31 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/4 "2003-03-27T05:31:34Z")

</div>

In article [1048739230.024452.29873.nullmailer@picachu.netlab.jp](mailto:1048739230.024452.29873.nullmailer@picachu.netlab.jp),

> **···**
>
> Yukihiro Matsumoto [matz@ruby-lang.org](mailto:matz@ruby-lang.org) wrote:
> 
> > Hi,
> > 
> > In message “case not calling class’ ‘===’ method?” \> on 03/03/27, Phil Tomson [ptkwt@shell1.aracnet.com](mailto:ptkwt@shell1.aracnet.com) writes:
> > 
> > > maybe I’m missing something obvious…
> > > 
> > > I’ve defined a ‘===’ operator for my class, but it doesn’t seem to get  
> > > called by case. Here’s the code:
> > 
> > In a code like
> > 
> > case a  
> > when b  
> > …  
> > end
> > 
> > “===” is called like “b === a”, not “a === b”. I hope this explains  
> > what happened on your code.
> > 
> > ```
> > matz.
> > 
> > ```
> 
> Thanks matz. Could you explain why it is done this way?
> 
> Phil

---

<div class="post-metadata">

**Author:** ![Chris18](https://avatars.discourse-cdn.com/v4/letter/c/e8c25b/32.png) [@Chris18](https://rubytalk.org/u/Chris18)\
**Post date:** [27 March 2003 06:37 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/5 "2003-03-27T06:37:40Z")

</div>

Thanks matz. Could you explain why it is done this way?

> **···**
>
> ----- Original Message -----  
> From: “Phil Tomson” [ptkwt@shell1.aracnet.com](mailto:ptkwt@shell1.aracnet.com)
> 
> * * *
> 
> Well, I’m not Matz, but I’ll give it a shot…
> 
> It works this way because this is how you want it. 🙂
> 
> In a case statement, you are trying to fit an object into one of many  
> different categories. You could try to have every object figure out what  
> categories it belongs to (terribly difficult), or you could have each  
> category figure out what belongs in it (easy).
> 
> Just look at some examples of case statements:
> 
> x = 5
> 
> case x  
> when 4 then …  
> when 5 then …  
> …  
> end
> 
> case x  
> when String then …  
> when Fixnum then …  
> …  
> end
> 
> case x  
> when 0…3 then …  
> when 3…6 then …  
> …  
> end
> 
> Imagine trying to code Fixnum#=== with this in mind:
> 
> class Fixnum  
> def === other  
> if other.kind\_of? Fixnum  
> self == other  
> elsif other.kind\_of? Module  
> self.kind\_of? other  
> elsif other.kind\_of? Range  
> …  
> …  
> end  
> end  
> end
> 
> You’d almost have to use a case statement! Seem like a bad idea yet? If  
> not, imagine the code in String#=== or Array#===; most of it would be  
> identical to what is in Fixnum#===.
> 
> The current system is definitely the Right Way.
> 
> Chris

---

<div class="post-metadata">

**Author:** ![Ptkwt1](https://avatars.discourse-cdn.com/v4/letter/p/85e7bf/32.png) [@Ptkwt1](https://rubytalk.org/u/Ptkwt1)\
**Post date:** [27 March 2003 19:14 UTC](https://rubytalk.org/t/case-not-calling-class-method/5368/6 "2003-03-27T19:14:43Z")

</div>

In article [060c01c2f42b$9fa30fb0$6401a8c0@MELONBALLER](mailto:060c01c2f42b$9fa30fb0$6401a8c0@MELONBALLER),

> **···**
>
> Chris Pine [nemo@hellotree.com](mailto:nemo@hellotree.com) wrote:
> 
> > ----- Original Message -----  
> > From: “Phil Tomson” [ptkwt@shell1.aracnet.com](mailto:ptkwt@shell1.aracnet.com)
> > 
> > ## Thanks matz. Could you explain why it is done this way?
> > 
> > Well, I’m not Matz, but I’ll give it a shot…
> > 
> > It works this way because this is how you want it. 🙂
> > 
> > In a case statement, you are trying to fit an object into one of many  
> > different categories. You could try to have every object figure out what  
> > categories it belongs to (terribly difficult), or you could have each  
> > category figure out what belongs in it (easy).
> > 
> > Just look at some examples of case statements:
> > 
> > x = 5
> > 
> > case x  
> > when 4 then …  
> > when 5 then …  
> > …  
> > end
> > 
> > case x  
> > when String then …  
> > when Fixnum then …  
> > …  
> > end
> > 
> > case x  
> > when 0…3 then …  
> > when 3…6 then …  
> > …  
> > end
> > 
> > Imagine trying to code Fixnum#=== with this in mind:
> > 
> > class Fixnum  
> > def === other  
> > if other.kind\_of? Fixnum  
> > self == other  
> > elsif other.kind\_of? Module  
> > self.kind\_of? other  
> > elsif other.kind\_of? Range  
> > …  
> > …  
> > end  
> > end  
> > end
> > 
> > You’d almost have to use a case statement! Seem like a bad idea yet? If  
> > not, imagine the code in String#=== or Array#===; most of it would be  
> > identical to what is in Fixnum#===.
> > 
> > The current system is definitely the Right Way.
> > 
> > Chris
> 
> Makes sense… Thanks for the explanation.
> 
> Phil
