Skip to content

Commit

Permalink
feat(utils): add protected option for Method#defined?
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Apr 23, 2023
1 parent bb16022 commit 2bfd1f6
Show file tree
Hide file tree
Showing 2 changed files with 500 additions and 36 deletions.
53 changes: 46 additions & 7 deletions lib/convenient_service/utils/method/defined.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ module ConvenientService
module Utils
module Method
class Defined < Support::Command
METHOD_DEFINED_CHECKERS = {
public: ->(klass, method) { klass.public_method_defined?(method) },
protected: ->(klass, method) { klass.protected_method_defined?(method) },
private: ->(klass, method) { klass.private_method_defined?(method) }
}

##
# @!attribute [r] method
# @return [Class]
Expand All @@ -17,32 +23,65 @@ class Defined < Support::Command
attr_reader :klass

##
# @!attribute [r] klass
# @return [Class]
# @!attribute [r] public
# @return [Boolean]
#
attr_reader :public

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

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

##
# @param method [Symbol, String]
# @param klass [Class]
# @param public [Boolean]
# @param protected [Boolean]
# @param private [Boolean]
# @return [void]
#
def initialize(method, klass, private: false)
# @internal
# NOTE: `protected` is set to `true` by default to keep the same semantics as `Module#method_defined?`.
# - https://ruby-doc.org/core-3.1.0/Module.html#method-i-method_defined-3F
#
def initialize(method, klass, public: true, protected: true, private: false)
@method = method.to_s
@klass = klass
@public = public
@protected = protected
@private = private
end

##
# @return [void]
#
def call
return true if klass.public_method_defined?(method)
return true if klass.protected_method_defined?(method)
return false if selected_visibilities.none?

selected_visibilities.any? { |visibility| method_defined?(visibility) }
end

return klass.private_method_defined?(method) if private
##
# @return [Array<Symbol>]
#
def selected_visibilities
{public: public, protected: protected, private: private}.keep_if { |_, should_be_checked| should_be_checked }.keys
end

false
##
# @param visibility [Symbol]
# @return [Boolean]
#
def method_defined?(visibility)
METHOD_DEFINED_CHECKERS[visibility].call(klass, method)
end
end
end
Expand Down
Loading

0 comments on commit 2bfd1f6

Please sign in to comment.