Skip to content

Instantly share code, notes, and snippets.

@OutlawAndy
Created December 3, 2024 02:51
Show Gist options
  • Save OutlawAndy/c7f31cef1e28b445ba45d523d87b4359 to your computer and use it in GitHub Desktop.
Save OutlawAndy/c7f31cef1e28b445ba45d523d87b4359 to your computer and use it in GitHub Desktop.
General purpose comparator interface I've occasionally found useful when testing complex objects.
class ObjectComparator < BasicObject
include ::Enumerable
extend ::Forwardable
def initialize(*members)
@members = members.flatten(1)
end
def_delegators :@members, :to_a, :each, :<=>, :==, :eql?, :hash
def __getobj__ = @members
def __id__ = @members.pluck(:id)
def to_s = _compare(:to_s).to_a.to_s
def inspect = _compare(:inspect).to_a
private
def _compare(method_name, *args, &)
::ObjectComparator.new(@members.map { _1.send(method_name, *args, &) })
end
def method_missing(method, *args, &)
@members.all? { _1.respond_to?(method) } ? _compare(method, *args, &) : super
end
def respond_to_missing?(method, *)
public_methods.include?(method) || @members.all? { _1.respond_to?(method) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment