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