Skip to content

Instantly share code, notes, and snippets.

@matheussilvasantos
Created September 12, 2019 12:10
Show Gist options
  • Save matheussilvasantos/a42fd23136162a16d4bb89839c4ad6b2 to your computer and use it in GitHub Desktop.
Save matheussilvasantos/a42fd23136162a16d4bb89839c4ad6b2 to your computer and use it in GitHub Desktop.
Rest
module REST
def self.OAuth(client)
REST::OAuth.new(client)
end
class OAuth < Module
def initialize(client)
@client = client
freeze
end
private
def included(descendant)
super
descendant.send(:include, Methods)
end
def define_methods
define_cmp_method
define_hash_method
define_inspect_method if inspect
end
# Define an #cmp? method based on the instance's values identified by #keys
#
# @return [undefined]
#
# @api private
def define_cmp_method
keys = @keys
define_method(:cmp?) do |comparator, other|
keys.all? do |key|
__send__(key).public_send(comparator, other.__send__(key))
end
end
private :cmp?
end
# Define a #hash method based on the instance's values identified by #keys
#
# @return [undefined]
#
# @api private
def define_hash_method
keys = @keys
define_method(:hash) do | |
keys.map(&method(:send)).push(self.class).hash
end
end
# Define an inspect method that reports the values of the instance's keys
#
# @return [undefined]
#
# @api private
def define_inspect_method
keys = @keys
define_method(:inspect) do | |
klass = self.class
name = klass.name || klass.inspect
"#<#{name}#{keys.map { |key| " #{key}=#{__send__(key).inspect}" }.join}>"
end
end
# The comparison methods
module Methods
# Compare the object with other object for equality
#
# @example
# object.eql?(other) # => true or false
#
# @param [Object] other
# the other object to compare with
#
# @return [Boolean]
#
# @api public
def eql?(other)
instance_of?(other.class) && cmp?(__method__, other)
end
# Compare the object with other object for equivalency
#
# @example
# object == other # => true or false
#
# @param [Object] other
# the other object to compare with
#
# @return [Boolean]
#
# @api public
def ==(other)
other.is_a?(self.class) && cmp?(__method__, other)
end
end # module Methods
end # class Equalizer
end
@ivopt
Copy link

ivopt commented Sep 12, 2019

PS: I think it would be possible to build a facilitator that would get you rid of all this boilerplate (the define_methods, the base.send :include, Methods, and possibly even the define_XXX_methods...

Sounds like a nice weekend challenge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment