代码之家  ›  专栏  ›  技术社区  ›  Pete Hodgson

在ruby中实现平等的正确方法是什么

  •  42
  • Pete Hodgson  · 技术社区  · 15 年前

    对于类似于结构的简单类:

    class Tiger
      attr_accessor :name, :num_stripes
    end
    

    正确实现平等的正确方法是什么? == , === , eql? ,etc可以工作,因此类的实例在集合、散列等中可以很好地发挥作用。

    编辑

    另外,当您希望基于未在类外公开的状态进行比较时,实现相等性的好方法是什么?例如:

    class Lady
      attr_accessor :name
    
      def initialize(age)
        @age = age
      end
    end
    

    在这里,我希望我的平等方法考虑到年龄,但这位女士不会向客户透露她的年龄。在这种情况下,我需要使用instance_variable_get吗?

    3 回复  |  直到 9 年前
        1
  •  67
  •   Wayne Conrad    9 年前

    若要简化具有多个状态变量的对象的比较运算符,请创建将对象的所有状态作为数组返回的方法。然后比较两种状态:

    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
    

    此外,如果希望类的实例可用作哈希键,请添加:

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

    这些需要公开。

        2
  •  18
  •   jvenezia    10 年前

    要同时测试所有实例变量的相等性,请执行以下操作:

    def ==(other)
      other.class == self.class && other.state == self.state
    end
    
    def state
      self.instance_variables.map { |variable| self.instance_variable_get variable }
    end
    
        3
  •  1
  •   Robert K    15 年前

    通常与 == 操作员。

    def == (other)
      if other.class == self.class
        @name == other.name && @num_stripes == other.num_stripes
      else
        false
      end
    end