lib/convenient_service/utils/method/defined.rb in convenient_service-0.12.0 vs lib/convenient_service/utils/method/defined.rb in convenient_service-0.13.0
- old
+ new
@@ -2,10 +2,16 @@
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]
#
attr_reader :method
@@ -15,34 +21,72 @@
# @return [Class]
#
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.method_defined?(method)
+ return false if selected_visibilities.none?
- return klass.private_method_defined?(method) if private
+ selected_visibilities.any? { |visibility| method_defined?(visibility) }
+ end
- false
+ ##
+ # @return [Array<Symbol>]
+ #
+ # @internal
+ # NOTE: `keep_if` seems more readable than `select` (just a personal feeling).
+ # It is safe to use `keep_if` since a new hash is created. Prefer `select` in a general case, since it is NOT mutable.
+ #
+ def selected_visibilities
+ @selected_visibilities ||= {public: public, protected: protected, private: private}.keep_if { |_, should_be_checked| should_be_checked }.keys
+ end
+
+ ##
+ # @param visibility [Symbol]
+ # @return [Boolean]
+ #
+ def method_defined?(visibility)
+ METHOD_DEFINED_CHECKERS[visibility].call(klass, method)
end
end
end
end
end