Equalizer

A simple mixin that can be used to add instance variable based equality, equivalence and inspection methods to your objects.

Usage

require "dry/core"

class GeoLocation
  include Dry::Core::Equalizer(:latitude, :longitude)

  attr_reader :latitude, :longitude

  def initialize(latitude, longitude)
    @latitude, @longitude = latitude, longitude
  end
end

point_a = GeoLocation.new(1, 2)
point_b = GeoLocation.new(1, 2)
point_c = GeoLocation.new(2, 2)

point_a.inspect    # => "#<GeoLocation latitude=1 longitude=2>"

point_a == point_b           # => true
point_a.hash == point_b.hash # => true
point_a.eql?(point_b)        # => true
point_a.equal?(point_b)      # => false

point_a == point_c           # => false
point_a.hash == point_c.hash # => false
point_a.eql?(point_c)        # => false
point_a.equal?(point_c)      # => false

Configuration options

inspect

Use inspect option to skip #inspect method overloading:

class Foo
  include Dry::Core::Equalizer(:a, inspect: false)

  attr_reader :a, :b

  def initialize(a, b)
    @a, @b = a, b
  end
end

Foo.new(1, 2).inspect
# => "#<Foo:0x00007fbc9c0487f0 @a=1, @b=2>"

immutable

For objects that are immutable it doesn't make sense to calculate #hash every time it's called. To memoize hash use immutable option:

class ImmutableHash
  include Dry::Core::Equalizer(:foo, :bar, immutable: true)

  attr_accessor :foo, :bar

  def initialize(foo, bar)
    @foo, @bar = foo, bar
  end
end

obj = ImmutableHash.new('foo', 'bar')
old_hash = obj.hash
obj.foo = 'changed'
old_hash == obj.hash
# => true

octocatEdit on GitHub