What's the right way to implement equality in ruby

后端 未结 3 1278
攒了一身酷
攒了一身酷 2020-12-25 09:58

For a simple struct-like class:

class Tiger
  attr_accessor :name, :num_stripes
end

what is the correct way to implement equality correctly

相关标签:
3条回答
  • 2020-12-25 10:21

    Usually with the == operator.

    def == (other)
      if other.class == self.class
        @name == other.name && @num_stripes == other.num_stripes
      else
        false
      end
    end
    
    0 讨论(0)
  • 2020-12-25 10:38

    To simplify comparison operators for objects with more than one state variable, create a method that returns all of the object's state as an array. Then just compare the two states:

    class Thing
    
      def initialize(a, b, c)
        @a = a
        @b = b
        @c = c
      end
    
      def ==(o)
        o.class == self.class && o.state == state
      end
    
      protected
    
      def state
        [@a, @b, @c]
      end
    
    end
    
    p Thing.new(1, 2, 3) == Thing.new(1, 2, 3)    # => true
    p Thing.new(1, 2, 3) == Thing.new(1, 2, 4)    # => false
    

    Also, if you want instances of your class to be usable as a hash key, then add:

      alias_method :eql?, :==
    
      def hash
        state.hash
      end
    

    These need to be public.

    0 讨论(0)
  • 2020-12-25 10:41

    To test all your instance variables equality at once:

    def ==(other)
      other.class == self.class && other.state == self.state
    end
    
    def state
      self.instance_variables.map { |variable| self.instance_variable_get variable }
    end
    
    0 讨论(0)
提交回复
热议问题