Sha256: 39bf0be7a207817597cea8102abab7fec8e7729bbeed18048dbe69c5ea1ef4a1

Contents?: true

Size: 1.85 KB

Versions: 1

Compression:

Stored size: 1.85 KB

Contents

# frozen_string_literal: true

require_relative 'tiny_hooks/version'

# TinyHooks is the gem to easily define hooks.
# `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)
    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
           when :after
             proc do |*args, **kwargs, &blk|
               original_method.bind_call(self, *args, **kwargs, &blk)
               instance_exec(*args, **kwargs, &block)
             end
           when :around
             proc do |*args, **kwargs, &blk|
               wrapper = -> { original_method.bind_call(self, *args, **kwargs, &blk) }
               instance_exec(wrapper, *args, **kwargs, &block)
             end
           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)
  end

  private

  def registry
    @registry ||= {}
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
tiny_hooks-0.1.0 lib/tiny_hooks.rb