class AroundTheWorld::MethodWrapper
Attributes
allow_undefined_method[R]
block[R]
method_name[R]
prevent_double_wrapping_for[R]
target[R]
Public Class Methods
new(method_name:, target:, prevent_double_wrapping_for: nil, allow_undefined_method: false, &block)
click to toggle source
@param :method_name [String, Symbol] The name of the method to be wrapped. @param :target [Module] The class or module containing the method to be wrapped. @param :prevent_double_wrapping_for [String, Symbol]
An identifier to define the proxy module's purpose in the ancestor tree. A method can only be wrapped once for a given purpose, though it can be wrapped again for other purposes, or for no given purpose.
@param :allow_undefined_method [Boolean] When false, an error is raised if the wrapped method is not
explicitly defined by the target. Default: false
@block The block that will be executed when the method is invoked.
Should always call super, at least conditionally.
# File lib/around_the_world/method_wrapper.rb, line 30 def initialize(method_name:, target:, prevent_double_wrapping_for: nil, allow_undefined_method: false, &block) raise TypeError, "target must be a module or a class" unless target.is_a?(Module) @method_name = method_name.to_sym @target = target @prevent_double_wrapping_for = prevent_double_wrapping_for || nil @allow_undefined_method = allow_undefined_method @block = block end
wrap(**args, &block)
click to toggle source
Passes arguments directly to {#new} - see {#initialize} for full docs
# File lib/around_the_world/method_wrapper.rb, line 13 def wrap(**args, &block) new(**args, &block).wrap end
Public Instance Methods
wrap()
click to toggle source
Defines the wrapped method inside a proxy module and prepends the proxy module to the target module if necessary.
# File lib/around_the_world/method_wrapper.rb, line 41 def wrap ensure_method_defined! prevent_double_wrapping! if prevent_double_wrapping? define_proxy_method target.prepend proxy_module unless target.ancestors.include?(proxy_module) end
Private Instance Methods
define_proxy_method()
click to toggle source
# File lib/around_the_world/method_wrapper.rb, line 70 def define_proxy_method proxy_module.define_method(method_name, &block) proxy_module.instance_exec(method_name, method_privacy) do |method_name, method_privacy| case method_privacy when :protected protected method_name when :private private method_name end end end
ensure_method_defined!()
click to toggle source
# File lib/around_the_world/method_wrapper.rb, line 57 def ensure_method_defined! return if allow_undefined_method return if target.instance_methods(true).include?(method_name) || target.private_method_defined?(method_name) raise MethodNotDefinedError, "#{target} does not define :#{method_name}" end
method_privacy()
click to toggle source
# File lib/around_the_world/method_wrapper.rb, line 83 def method_privacy if target.protected_method_defined?(method_name) :protected elsif target.private_method_defined?(method_name) :private end end
prevent_double_wrapping!()
click to toggle source
# File lib/around_the_world/method_wrapper.rb, line 64 def prevent_double_wrapping! return unless already_wrapped?(method_name, target, prevent_double_wrapping_for) raise DoubleWrapError, "Module #{proxy_module} already defines the method :#{method_name}" end
prevent_double_wrapping?()
click to toggle source
# File lib/around_the_world/method_wrapper.rb, line 53 def prevent_double_wrapping? prevent_double_wrapping_for.present? end
proxy_module()
click to toggle source
@return [AroundTheWorld::ProxyModule] The proxy module upon which the method wrapper will be defined
# File lib/around_the_world/method_wrapper.rb, line 92 def proxy_module @proxy_module ||= proxy_module_with_purpose(method_name, target, prevent_double_wrapping_for) end