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

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

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

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 writes:

In article 1048739230.024452.29873.nullmailer@picachu.netlab.jp,

···

Yukihiro Matsumoto matz@ruby-lang.org wrote:

Hi,

In message “case not calling class’ ‘===’ method?” > on 03/03/27, Phil Tomson 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

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

···

----- Original Message -----
From: “Phil Tomson” 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. :slight_smile:

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

In article 060c01c2f42b$9fa30fb0$6401a8c0@MELONBALLER,

···

Chris Pine nemo@hellotree.com wrote:

----- Original Message -----
From: “Phil Tomson” 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. :slight_smile:

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