Skip to content

Commit

Permalink
feat(utils): introduce Object.own_method
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed May 18, 2024
1 parent 10971c5 commit 39e3c08
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,8 @@ def call_method(method)
# @internal
# TODO: A possible bottleneck. Should be removed if receives negative feedback.
#
# NOTE: `own_method.bind(organizer).call` is logically the same as `own_method.bind_call(organizer)`.
# - https://ruby-doc.org/core-2.7.1/UnboundMethod.html#method-i-bind_call
# - https://blog.saeloun.com/2019/10/17/ruby-2-7-adds-unboundmethod-bind_call-method.html
#
# TODO: Util.
#
def own_method
method = Utils::Module.get_own_instance_method(organizer.class, method_name, private: true)

return unless method

method.bind(organizer)
Utils.memoize_including_falsy_values(self, :@own_method) { Utils::Object.own_method(organizer, method_name, private: true) }
end

##
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,44 +88,22 @@ def fallback_error_result
##
# @return [Method, nil]
#
# @internal
# TODO: Util.
# TODO: Comprehensive suite.
#
def fallback_failure_result_own_method
method = Utils::Module.get_own_instance_method(service.class, :fallback_failure_result, private: true)

return unless method

method.bind(service)
Utils::Object.own_method(service, :fallback_failure_result, private: true)
end

##
# @return [Method, nil]
#
# @internal
# TODO: Util.
#
def fallback_error_result_own_method
method = Utils::Module.get_own_instance_method(service.class, :fallback_error_result, private: true)

return unless method

method.bind(service)
Utils::Object.own_method(service, :fallback_error_result, private: true)
end

##
# @return [Method, nil]
#
# @internal
# TODO: Util.
#
def fallback_result_own_method
method = Utils::Module.get_own_instance_method(service.class, :fallback_result, private: true)

return unless method

method.bind(service)
Utils::Object.own_method(service, :fallback_result, private: true)
end

##
Expand Down
15 changes: 15 additions & 0 deletions lib/convenient_service/utils/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative "object/clamp_class"
require_relative "object/duck_class"
require_relative "object/get_own_method"
require_relative "object/instance_variable_delete"
require_relative "object/instance_variable_fetch"
require_relative "object/memoize_including_falsy_values"
Expand Down Expand Up @@ -54,6 +55,20 @@ def memoize_including_falsy_values(...)
MemoizeIncludingFalsyValues.call(...)
end

##
# @example
# object = Object.new.tap { |object| object.instance_eval { self.class.attr_reader :foo } }
#
# ConvenientService::Utils::Object.own_method(object, :foo)
# # => #<Method: #<Object:0x0000555e524252d8>.foo() ...>
#
# ConvenientService::Utils::Object.own_method(object, :puts)
# # => nil
#
def own_method(...)
GetOwnMethod.call(...)
end

##
# @example
# ConvenientService::Utils::Object.resolve_type("foo")
Expand Down
54 changes: 54 additions & 0 deletions lib/convenient_service/utils/object/get_own_method.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

module ConvenientService
module Utils
module Object
class GetOwnMethod < Support::Command
##
# @!attribute [r] object
# @return [Object] Can be any type.
#
attr_reader :object

##
# @!attribute [r] method_name
# @return [Symbol, String]
#
attr_reader :method_name

##
# @!attribute [r] private
# @return [Boolean]
#
attr_reader :private

##
# @param object [Object] Can be any type.
# @param method_name [Symbol, String]
# @param private [Boolean]
#
def initialize(object, method_name, private: false)
@object = object
@method_name = method_name
@private = private
end

##
# @return [Class]
#
# @internal
# NOTE: `own_method.bind(object).call` is logically the same as `own_method.bind_call(object)`.
# - https://ruby-doc.org/core-2.7.1/UnboundMethod.html#method-i-bind_call
# - https://blog.saeloun.com/2019/10/17/ruby-2-7-adds-unboundmethod-bind_call-method.html
#
def call
own_method = Utils::Module.get_own_instance_method(object.class, method_name, private: private)

return unless own_method

own_method.bind(object)
end
end
end
end
end

0 comments on commit 39e3c08

Please sign in to comment.