module Equatable
Make it easy to define equality and hash methods.
Constants
- VERSION
Attributes
Holds all attributes used for comparison.
@return [Array<Symbol>]
@api private
Public Class Methods
Hook into module inclusion.
@param [Module] base
the module or class including Equatable
@return [self]
@api private
# File lib/equatable.rb, line 15 def self.included(base) super base.extend(self) base.class_eval do include Methods define_methods end end
Public Instance Methods
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
# File lib/equatable.rb, line 40 def attr_reader(*args) super comparison_attrs.concat(args) end
Copy the comparison_attrs
into the subclass.
@param [Class] subclass
@api private
# File lib/equatable.rb, line 50 def inherited(subclass) super subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup) end
Private Instance Methods
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 84 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 class instance comparison_attrs
as an empty array.
@return [undefined]
@api private
# File lib/equatable.rb, line 74 def define_comparison_attrs instance_variable_set('@comparison_attrs', []) end
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 98 def define_hash define_method(:hash) do klass = self.class attrs = klass.comparison_attrs ([klass] + attrs.map { |attr| send(attr) }).hash end end
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 112 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 all methods needed for ensuring object's equality.
@return [undefined]
@api private
# File lib/equatable.rb, line 62 def define_methods define_comparison_attrs define_compare define_hash define_inspect end