Class: Pry::Hooks

Inherits:
Object show all
Defined in:
lib/pry/hooks.rb

Overview

Implements a hooks system for Pry. A hook is a callable that is associated with an event. A number of events are currently provided by Pry, these include: :when_started, :before_session, :after_session. A hook must have a name, and is connected with an event by the Pry::Hooks#add_hook method.

Examples:

Adding a hook for the :before_session event.

Pry.config.hooks.add_hook(:before_session, :say_hi) do
  puts "hello"
end

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHooks



29
30
31
# File 'lib/pry/hooks.rb', line 29

def initialize
  @hooks = {}
end

Class Method Details

.from_hash(hash) ⇒ Pry::Hooks

Converts a hash to a Pry::Hooks instance. All hooks defined this way are anonymous. This functionality is primarily to provide backwards-compatibility with the old hash-based hook system in Pry versions < 0.9.8



20
21
22
23
24
25
26
27
# File 'lib/pry/hooks.rb', line 20

def self.from_hash(hash)
  return hash if hash.instance_of?(self)
  instance = new
  hash.each do |k, v|
    instance.add_hook(k, nil, v)
  end
  instance
end

Instance Method Details

#add_hook(event_name, hook_name, callable = nil) { ... } ⇒ Pry:Hooks

Add a new hook to be executed for the name even.

Examples:

Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }

Yields:

  • The block to use as the callable (if callable parameter not provided)



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/pry/hooks.rb', line 98

def add_hook(event_name, hook_name, callable=nil, &block)
  @hooks[event_name] ||= []

  # do not allow duplicates, but allow multiple `nil` hooks
  # (anonymous hooks)
  if hook_exists?(event_name, hook_name) && !hook_name.nil?
    raise ArgumentError, "Hook with name '#{hook_name}' already defined!"
  end

  if !block && !callable
    raise ArgumentError, "Must provide a block or callable."
  end

  # ensure we only have one anonymous hook
  @hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil?

  if block
    @hooks[event_name] << [hook_name, block]
  elsif callable
    @hooks[event_name] << [hook_name, callable]
  end

  self
end

#clear_allObject

Remove all events and hooks, clearing out the Pry::Hooks instance completely.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.clear_all


219
220
221
# File 'lib/pry/hooks.rb', line 219

def clear_all
  @hooks = {}
end

#delete_hook(event_name, hook_name) ⇒ #call

Delete a hook for an event.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.delete_hook(:before_session, :say_hi)


188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/pry/hooks.rb', line 188

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

#delete_hooks(event_name) ⇒ Object Also known as: clear

Clear all hooks functions for a given event.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.delete_hook(:before_session)


208
209
210
# File 'lib/pry/hooks.rb', line 208

def delete_hooks(event_name)
  @hooks[event_name] = []
end

#errorsObject



48
49
50
# File 'lib/pry/hooks.rb', line 48

def errors
  @errors ||= []
end

#exec_hook(event_name, *args, &block) ⇒ Object

Execute the list of hooks for the event_name event.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!"


130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/pry/hooks.rb', line 130

def exec_hook(event_name, *args, &block)
  @hooks[event_name] ||= []

  @hooks[event_name].map do |hook_name, callable|
    begin
      callable.call(*args, &block)
    rescue RescuableException => e
      errors << e
      e
    end
  end.last
end

#get_hook(event_name, hook_name) ⇒ #call

Return a specific hook for a given event.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!"


161
162
163
164
165
# File 'lib/pry/hooks.rb', line 161

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

#get_hooks(event_name) ⇒ Hash

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).

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.get_hooks(:before_session) #=> {:say_hi=>#<Proc:0x00000101645e18@(pry):9>}


175
176
177
178
# File 'lib/pry/hooks.rb', line 175

def get_hooks(event_name)
  @hooks[event_name] ||= []
  Hash[@hooks[event_name]]
end

#hook_count(event_name) ⇒ Fixnum

Return the number of hook functions registered for the event_name event.

Examples:

my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
my_hooks.count(:before_session) #=> 1


149
150
151
152
# File 'lib/pry/hooks.rb', line 149

def hook_count(event_name)
  @hooks[event_name] ||= []
  @hooks[event_name].size
end

#hook_exists?(event_name, hook_name) ⇒ Boolean



226
227
228
# File 'lib/pry/hooks.rb', line 226

def hook_exists?(event_name, hook_name)
  !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name })
end

#initialize_copy(orig) ⇒ Object

Ensure that duplicates have their @hooks object



34
35
36
37
38
39
40
41
# File 'lib/pry/hooks.rb', line 34

def initialize_copy(orig)
  hooks_dup = @hooks.dup
  @hooks.each do |k, v|
    hooks_dup[k] = v.dup
  end

  @hooks = hooks_dup
end

#merge(other) ⇒ Pry::Hooks

Return a new Pry::Hooks instance containing a merge of the contents of two Pry:Hooks instances,

Examples:

hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
Pry::Hooks.new.merge(hooks)


84
85
86
87
88
# File 'lib/pry/hooks.rb', line 84

def merge(other)
  self.dup.tap do |v|
    v.merge!(other)
  end
end

#merge!(other) ⇒ Pry:Hooks

Destructively merge the contents of two Pry:Hooks instances.

Examples:

hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
Pry::Hooks.new.merge!(hooks)


58
59
60
61
62
63
64
# File 'lib/pry/hooks.rb', line 58

def merge!(other)
  @hooks.merge!(other.dup.hooks) do |key, v1, v2|
    merge_arrays(v1, v2)
  end

  self
end

#merge_arrays(array1, array2) ⇒ Object (private)



66
67
68
# File 'lib/pry/hooks.rb', line 66

def merge_arrays(array1, array2)
  uniq_keeping_last(array1 + array2, &:first)
end

#uniq_keeping_last(input, &block) ⇒ Object (private)



71
72
73
74
75
# File 'lib/pry/hooks.rb', line 71

def uniq_keeping_last(input, &block)
  hash, output = {}, []
  input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) }
  output
end