A ruby gem to decorate your methods and run arbitrary hooks before, after
or around them. It is similar on how Rails does with before_action,
after_action and around_action but this for any class.
It automatically wraps the configured methods to call the hooks before,
after or around them.
Add the following line to your Gemfile:
gem 'captain_hook', git: 'https://github.com/factorialco/captain_hook.git', branch: 'main'Then bundle install
In order to inject the hook behavior, you need to include the CaptainHook
module in your class and use the hook method to decorate the methods you want
to hook.
class MyService
include CaptainHook
hook :before, methods: [:cook], hook: CookHook.new, inject: [:policy_context]
hook :before, methods: [:deliver], hook: ErroringHook.new
hook :before,
hook: BeforeAllHook.new,
exclude: [:serve],
skip_when: ->(_args, kwargs) { !kwargs[:dto] }
hook :after, methods: [:prepare], hook: PrepareHook.new
hook :after, methods: [:invented_one], hook: PrepareHook.new
hook :around,
methods: %i[serve foo],
hook: ServeHook.new,
skip_when: ->(_args, kwargs) { kwargs[:dto] }
def prepare(dto:); end
def cook; end
def serve; end
def deliver; end
endParameters:
methods: an array of method names to hook. If not specified, it will hook all methods.hook: the instance of the hook to run.- inject: The hook will receive these additional keyword arguments from the class hosting the method.
exclude: an array of method names to exclude from being hooked.- skip_when: a lambda that receives the positional and keyword arguments of the method being decorated and returns a boolean to skip the hook.
You need to implement a class with the #call method.
This method will receive the following positional parameters:
- klass: the class where the method is defined
- method: the method name
- block: the original method (useful for around hooks)
Additionally it will receive the positional and keyword arguments of the original method being decorated.
You can inject additional keyword parameters by using the inject parameter
when registering the hook.
- You can not call super from a child class decorated method, you will enter in an infinite loop