module Equatable

Make it easy to define equality and hash methods.

Constants

VERSION

Attributes

comparison_attrs[R]

Holds all attributes used for comparison.

@return [Array<Symbol>]

@api private

Public Class Methods

included(base) click to toggle source

Hook into module inclusion.

@param [Module] base

the module or class including Equatable

@return [self]

@api private

Calls superclass method
# File lib/equatable.rb, line 14
def self.included(base)
  super
  base.extend(self)
  base.class_eval do
    include Methods
    define_methods
  end
end

Public Instance Methods

attr_reader(*args) click to toggle source

Objects that include this module are assumed to be value objects. It is also assumed that the only values that affect the results of equality comparison are the values of the object's attributes.

@param [Array<Symbol>] *args

@return [undefined]

@api public

Calls superclass method
# File lib/equatable.rb, line 39
def attr_reader(*args)
  super
  comparison_attrs.concat(args)
end
inherited(subclass) click to toggle source

Copy the #comparison_attrs into the subclass.

@param [Class] subclass

@api private

Calls superclass method
# File lib/equatable.rb, line 49
def inherited(subclass)
  super
  subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup)
end

Private Instance Methods

define_compare() click to toggle source

Define a compare? method to check if the receiver is the same as the other object.

@return [undefined]

@api private

# File lib/equatable.rb, line 83
def define_compare
  define_method(:compare?) do |comparator, other|
    klass = self.class
    attrs = klass.comparison_attrs
    attrs.all? do |attr|
      other.respond_to?(attr) && send(attr).send(comparator, other.send(attr))
    end
  end
end
define_comparison_attrs() click to toggle source

Define class instance comparison_attrs as an empty array.

@return [undefined]

@api private

# File lib/equatable.rb, line 73
def define_comparison_attrs
  instance_variable_set('@comparison_attrs', [])
end
define_hash() click to toggle source

Define a hash method that ensures that the hash value is the same for the same instance attributes and their corresponding values.

@api private

# File lib/equatable.rb, line 97
def define_hash
  define_method(:hash) do
    klass = self.class
    attrs = klass.comparison_attrs
    ([klass] + attrs.map { |attr| send(attr) }).hash
  end
end
define_inspect() click to toggle source

Define an inspect method that shows the class name and the values for the instance's attributes.

@return [undefined]

@api private

# File lib/equatable.rb, line 111
def define_inspect
  define_method(:inspect) do
    klass = self.class
    name  = klass.name || klass.inspect
    attrs = klass.comparison_attrs
    "#<#{name}#{attrs.map { |attr| " #{attr}=#{send(attr).inspect}" }.join}>"
  end
end
define_methods() click to toggle source

Define all methods needed for ensuring object's equality.

@return [undefined]

@api private

# File lib/equatable.rb, line 61
def define_methods
  define_comparison_attrs
  define_compare
  define_hash
  define_inspect
end