lib/tiny_hooks.rb in tiny_hooks-0.1.0 vs lib/tiny_hooks.rb in tiny_hooks-0.2.0
- old
+ new
@@ -6,53 +6,73 @@
# `extend` this module and now you can define hooks with `define_hook` method.
# See the test file for more detailed usage.
module TinyHooks
class Error < StandardError; end
- # rubocop:disable Metrics/MethodLength
# Define hook with kind and target method
#
# @param [Symbol, String] kind the kind of the hook, possible values are: :before, :after and :around
# @param [Symbol, String] target the name of the targeted method
def define_hook(kind, target, &block)
+ raise ArgumentError, 'You must provide a block' unless block
+
original_method = instance_method(target)
body = case kind.to_sym
when :before
- proc do |*args, **kwargs, &blk|
- instance_exec(*args, **kwargs, &block)
- original_method.bind_call(self, *args, **kwargs, &blk)
- end
+ _before(original_method, &block)
when :after
- proc do |*args, **kwargs, &blk|
- original_method.bind_call(self, *args, **kwargs, &blk)
- instance_exec(*args, **kwargs, &block)
- end
+ _after(original_method, &block)
when :around
- proc do |*args, **kwargs, &blk|
- wrapper = -> { original_method.bind_call(self, *args, **kwargs, &blk) }
- instance_exec(wrapper, *args, **kwargs, &block)
- end
+ _around(original_method, &block)
else
raise Error, "#{kind} is not supported."
end
undef_method(target)
define_method(target, &body)
end
- # rubocop:enable Metrics/MethodLength
module_function :define_hook
- # Restore original method from the registry
- #
- # @param [Symbol, String] target the name of the method to restore
- def restore_original(target)
- original = registry.fetch(target.to_sym) { instance_method(target) }
- undef_method(target)
- define_method(target, original)
+ private
+
+ def _before(original_method, &block)
+ if RUBY_VERSION >= '2.7'
+ proc do |*args, **kwargs, &blk|
+ instance_exec(*args, **kwargs, &block)
+ original_method.bind_call(self, *args, **kwargs, &blk)
+ end
+ else
+ proc do |*args, &blk|
+ instance_exec(*args, &block)
+ original_method.bind(self).call(*args, &blk)
+ end
+ end
end
- private
+ def _after(original_method, &block)
+ if RUBY_VERSION >= '2.7'
+ proc do |*args, **kwargs, &blk|
+ original_method.bind_call(self, *args, **kwargs, &blk)
+ instance_exec(*args, **kwargs, &block)
+ end
+ else
+ proc do |*args, &blk|
+ original_method.bind(self).call(*args, &blk)
+ instance_exec(*args, &block)
+ end
+ end
+ end
- def registry
- @registry ||= {}
+ def _around(original_method, &block)
+ if RUBY_VERSION >= '2.7'
+ proc do |*args, **kwargs, &blk|
+ wrapper = -> { original_method.bind_call(self, *args, **kwargs, &blk) }
+ instance_exec(wrapper, *args, **kwargs, &block)
+ end
+ else
+ proc do |*args, &blk|
+ wrapper = -> { original_method.bind(self).call(*args, &blk) }
+ instance_exec(wrapper, *args, &block)
+ end
+ end
end
end