Search code examples
rubyincludecomparableenumerable

How to compare a class to any other arbitrary class via include? method


I have implemented comparable and enumerable so that I can use comparisons and include:

Given the simple class below:

class Card
  include Comparable
  include Enumerable
  attr_accessor :value

  def initialize(v)
    @value = v
  end

  def <=>(other)
    @value <=> other.value
  end

  def each
    yield @value
  end
end

Then:

c = Card.new(1) #so right now we have @value at 1

Neither of these include methods work though:

[1,3,4,5].include?(c)
c.include?([1,3,4,5])

Is it at all possible to use the include method to do this? I know I can do it another way, but i'd like to do it "ruby like"! (Assuming this is even the ruby like way...) I'm just getting into ruby from java and c++

Thanks in advance!


Solution

  • If you stare at your code long enough, you'll see. You implement a spaceship operator that assumes that other is a Card. But you invoke it on Fixnums! You need to do a little type checking there:

    class Card
      include Comparable
      include Enumerable
    
      attr_accessor :value
      def initialize(v)
        @value = v
      end
      def <=>(other)
        if other.is_a?(Card)
          @value <=> other.value
        else
          @value <=> other
        end
      end
    
      def each
        yield @value
      end
    end
    
    c = Card.new(1)
    
    [1,3,4,5].include?(c) # => true
    c.include?([1,3,4,5]) # => false # because 1 does not contain an array [1, 2, 3, 4, 5]