mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
c800c0f04f
Also the return value of exec_hook() is now the value of the last executed hook. Internally, hooks now use arrays (rather than hash). Also added a get_hooks() method. Updated tests to reflect these changes.
108 lines
3.6 KiB
Ruby
108 lines
3.6 KiB
Ruby
class Pry
|
|
class Hooks
|
|
|
|
def initialize
|
|
@hooks = {}
|
|
end
|
|
|
|
# Add a new hook to be executed for the `name` even.
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @param [Symbol] hook_name The name of the hook.
|
|
# @param [#call] callable The callable.
|
|
# @yield The block to use as the callable (if `callable` parameter not provided)
|
|
def add_hook(event_name, hook_name, callable=nil, &block)
|
|
@hooks[event_name] ||= []
|
|
|
|
# do not allow duplicates
|
|
raise ArgumentError, "Hook with name '#{hook_name}' already defined!" if hook_exists?(event_name, hook_name)
|
|
|
|
if block
|
|
@hooks[event_name] << [hook_name, block]
|
|
elsif callable
|
|
@hooks[event_name] << [hook_name, callable]
|
|
else
|
|
raise ArgumentError, "Must provide a block or callable."
|
|
end
|
|
|
|
self
|
|
end
|
|
|
|
# Execute the list of hooks for the `event_name` event.
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @param [Array] args The arguments to pass to each hook function.
|
|
# @return [Object] The return value of the last executed hook.
|
|
def exec_hook(event_name, *args, &block)
|
|
@hooks[event_name] ||= []
|
|
|
|
# silence warnings to get rid of 1.8's "warning: multiple values
|
|
# for a block parameter" warnings
|
|
Pry::Helpers::BaseHelpers.silence_warnings do
|
|
@hooks[event_name].map { |hook_name, callable| callable.call(*args, &block) }.last
|
|
end
|
|
end
|
|
|
|
# Return the number of hook functions registered for the `event_name` event.
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @return [Fixnum] The number of hook functions for `event_name`.
|
|
def hook_count(event_name)
|
|
@hooks[event_name] ||= []
|
|
@hooks[event_name].size
|
|
end
|
|
|
|
# Return a specific hook for a given event.
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @param [Symbol[ hook_name The name of the hook
|
|
# @return [#call] The requested hook.
|
|
def get_hook(event_name, hook_name)
|
|
@hooks[event_name] ||= []
|
|
hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name }
|
|
hook.last if hook
|
|
end
|
|
|
|
# Return the hash of hook names / hook functions for a
|
|
# given event. (Note that modifying the returned hash does not
|
|
# alter the hooks, use add_hook/delete_hook for that).
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @return [Hash] The hash of hook names / hook functions.
|
|
def get_hooks(event_name)
|
|
@hooks[event_name] ||= []
|
|
Hash[@hooks[event_name]]
|
|
end
|
|
|
|
# Delete a hook for an event.
|
|
# @param [Symbol] event_name The name of the event.
|
|
# @param [Symbol] hook_name The name of the hook.
|
|
# to delete.
|
|
# @return [#call] The deleted hook.
|
|
def delete_hook(event_name, hook_name)
|
|
@hooks[event_name] ||= []
|
|
deleted_callable = nil
|
|
|
|
@hooks[event_name].delete_if do |current_hook_name, callable|
|
|
if current_hook_name == hook_name
|
|
deleted_callable = callable
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
deleted_callable
|
|
end
|
|
|
|
# Clear all hooks functions for a given event.
|
|
# @param [String] event_name The name of the event.
|
|
def clear(event_name)
|
|
@hooks[event_name] = []
|
|
end
|
|
|
|
# @param [Symbol] event_name Name of the event.
|
|
# @param [Symbol] hook_name Name of the hook.
|
|
# @return [Boolean] Whether the hook by the name `hook_name`
|
|
# is defined for the event.
|
|
def hook_exists?(event_name, hook_name)
|
|
!!@hooks[event_name].find { |name, _| name == hook_name }
|
|
end
|
|
private :hook_exists?
|
|
|
|
end
|
|
end
|