Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you override the ruby case equality operator? (===)

I have a class that I want to compare to both strings and symbols in a case statement, so I thought that I just override the ===() method for my class and all would be gold. However my ===() method never gets called during the case statement. Any ideas?

Here is some example code, and what happens in a irb session:

class A
   def initialize(x)
      @x=x #note this isn't even required for this example
   end
   def ===(other)
      puts "in ==="
      return true
   end
end

irb(main):010:0> a=A.new("hi")
=> #
irb(main):011:0> case a
irb(main):012:1> when "hi" then 1
irb(main):013:1> else 2
irb(main):014:1> end
=> 2

(it never prints the message and should always return true anyway) Note that ideally I'd like to do a

def ===(other)
          #puts "in ==="
          return @x.===(other)
end

Thanks in advance.

like image 692
Marcin Avatar asked Mar 10 '09 10:03

Marcin


1 Answers

The expression after the 'case' keyword is the right hand side of the === expression, and the expression after the 'when' keyword is on the left hand side of the expression. So, the method that is being called is String.===, not A.===.

A quick approach to reversing the comparison:

class Revcomp
    def initialize(obj)
        @obj = obj
    end

    def ===(other)
        other === @obj
    end

    def self.rev(obj)
        Revcomp.new(obj)
    end
end

class Test
    def ===(other)
        puts "here"
    end
end

t = Test.new

case t
when Revcomp.rev("abc")
    puts "there"
else
    puts "somewhere"
end
like image 84
janm Avatar answered Sep 21 '22 10:09

janm