super-smart-mod 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/pry-0.16.0/CHANGELOG.md +1211 -0
  3. data/pry-0.16.0/LICENSE +25 -0
  4. data/pry-0.16.0/README.md +469 -0
  5. data/pry-0.16.0/bin/pry +13 -0
  6. data/pry-0.16.0/lib/pry/basic_object.rb +10 -0
  7. data/pry-0.16.0/lib/pry/block_command.rb +22 -0
  8. data/pry-0.16.0/lib/pry/class_command.rb +194 -0
  9. data/pry-0.16.0/lib/pry/cli.rb +211 -0
  10. data/pry-0.16.0/lib/pry/code/code_file.rb +114 -0
  11. data/pry-0.16.0/lib/pry/code/code_range.rb +73 -0
  12. data/pry-0.16.0/lib/pry/code/loc.rb +105 -0
  13. data/pry-0.16.0/lib/pry/code.rb +357 -0
  14. data/pry-0.16.0/lib/pry/code_object.rb +197 -0
  15. data/pry-0.16.0/lib/pry/color_printer.rb +66 -0
  16. data/pry-0.16.0/lib/pry/command.rb +520 -0
  17. data/pry-0.16.0/lib/pry/command_set.rb +418 -0
  18. data/pry-0.16.0/lib/pry/command_state.rb +36 -0
  19. data/pry-0.16.0/lib/pry/commands/amend_line.rb +103 -0
  20. data/pry-0.16.0/lib/pry/commands/bang.rb +24 -0
  21. data/pry-0.16.0/lib/pry/commands/bang_pry.rb +21 -0
  22. data/pry-0.16.0/lib/pry/commands/cat/abstract_formatter.rb +32 -0
  23. data/pry-0.16.0/lib/pry/commands/cat/exception_formatter.rb +90 -0
  24. data/pry-0.16.0/lib/pry/commands/cat/file_formatter.rb +77 -0
  25. data/pry-0.16.0/lib/pry/commands/cat/input_expression_formatter.rb +48 -0
  26. data/pry-0.16.0/lib/pry/commands/cat.rb +70 -0
  27. data/pry-0.16.0/lib/pry/commands/cd.rb +48 -0
  28. data/pry-0.16.0/lib/pry/commands/change_inspector.rb +34 -0
  29. data/pry-0.16.0/lib/pry/commands/change_prompt.rb +51 -0
  30. data/pry-0.16.0/lib/pry/commands/clear_screen.rb +20 -0
  31. data/pry-0.16.0/lib/pry/commands/code_collector.rb +182 -0
  32. data/pry-0.16.0/lib/pry/commands/disable_pry.rb +31 -0
  33. data/pry-0.16.0/lib/pry/commands/easter_eggs.rb +101 -0
  34. data/pry-0.16.0/lib/pry/commands/edit/exception_patcher.rb +29 -0
  35. data/pry-0.16.0/lib/pry/commands/edit/file_and_line_locator.rb +47 -0
  36. data/pry-0.16.0/lib/pry/commands/edit.rb +225 -0
  37. data/pry-0.16.0/lib/pry/commands/exit.rb +47 -0
  38. data/pry-0.16.0/lib/pry/commands/exit_all.rb +33 -0
  39. data/pry-0.16.0/lib/pry/commands/exit_program.rb +27 -0
  40. data/pry-0.16.0/lib/pry/commands/find_method.rb +199 -0
  41. data/pry-0.16.0/lib/pry/commands/fix_indent.rb +23 -0
  42. data/pry-0.16.0/lib/pry/commands/help.rb +171 -0
  43. data/pry-0.16.0/lib/pry/commands/hist.rb +182 -0
  44. data/pry-0.16.0/lib/pry/commands/import_set.rb +27 -0
  45. data/pry-0.16.0/lib/pry/commands/jump_to.rb +33 -0
  46. data/pry-0.16.0/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/pry-0.16.0/lib/pry/commands/ls/config.rb +54 -0
  48. data/pry-0.16.0/lib/pry/commands/ls/constants.rb +75 -0
  49. data/pry-0.16.0/lib/pry/commands/ls/formatter.rb +55 -0
  50. data/pry-0.16.0/lib/pry/commands/ls/globals.rb +50 -0
  51. data/pry-0.16.0/lib/pry/commands/ls/grep.rb +23 -0
  52. data/pry-0.16.0/lib/pry/commands/ls/instance_vars.rb +40 -0
  53. data/pry-0.16.0/lib/pry/commands/ls/interrogatable.rb +24 -0
  54. data/pry-0.16.0/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  55. data/pry-0.16.0/lib/pry/commands/ls/local_names.rb +37 -0
  56. data/pry-0.16.0/lib/pry/commands/ls/local_vars.rb +47 -0
  57. data/pry-0.16.0/lib/pry/commands/ls/ls_entity.rb +65 -0
  58. data/pry-0.16.0/lib/pry/commands/ls/methods.rb +55 -0
  59. data/pry-0.16.0/lib/pry/commands/ls/methods_helper.rb +50 -0
  60. data/pry-0.16.0/lib/pry/commands/ls/self_methods.rb +34 -0
  61. data/pry-0.16.0/lib/pry/commands/ls.rb +114 -0
  62. data/pry-0.16.0/lib/pry/commands/nesting.rb +29 -0
  63. data/pry-0.16.0/lib/pry/commands/play.rb +113 -0
  64. data/pry-0.16.0/lib/pry/commands/pry_backtrace.rb +30 -0
  65. data/pry-0.16.0/lib/pry/commands/pry_version.rb +21 -0
  66. data/pry-0.16.0/lib/pry/commands/raise_up.rb +38 -0
  67. data/pry-0.16.0/lib/pry/commands/reload_code.rb +74 -0
  68. data/pry-0.16.0/lib/pry/commands/reset.rb +22 -0
  69. data/pry-0.16.0/lib/pry/commands/ri.rb +75 -0
  70. data/pry-0.16.0/lib/pry/commands/save_file.rb +63 -0
  71. data/pry-0.16.0/lib/pry/commands/shell_command.rb +75 -0
  72. data/pry-0.16.0/lib/pry/commands/shell_mode.rb +30 -0
  73. data/pry-0.16.0/lib/pry/commands/show_doc.rb +84 -0
  74. data/pry-0.16.0/lib/pry/commands/show_info.rb +234 -0
  75. data/pry-0.16.0/lib/pry/commands/show_input.rb +22 -0
  76. data/pry-0.16.0/lib/pry/commands/show_source.rb +57 -0
  77. data/pry-0.16.0/lib/pry/commands/stat.rb +44 -0
  78. data/pry-0.16.0/lib/pry/commands/switch_to.rb +29 -0
  79. data/pry-0.16.0/lib/pry/commands/toggle_color.rb +28 -0
  80. data/pry-0.16.0/lib/pry/commands/watch_expression/expression.rb +43 -0
  81. data/pry-0.16.0/lib/pry/commands/watch_expression.rb +108 -0
  82. data/pry-0.16.0/lib/pry/commands/whereami.rb +205 -0
  83. data/pry-0.16.0/lib/pry/commands/wtf.rb +95 -0
  84. data/pry-0.16.0/lib/pry/config/attributable.rb +22 -0
  85. data/pry-0.16.0/lib/pry/config/lazy_value.rb +29 -0
  86. data/pry-0.16.0/lib/pry/config/memoized_value.rb +34 -0
  87. data/pry-0.16.0/lib/pry/config/value.rb +24 -0
  88. data/pry-0.16.0/lib/pry/config.rb +321 -0
  89. data/pry-0.16.0/lib/pry/control_d_handler.rb +28 -0
  90. data/pry-0.16.0/lib/pry/core_extensions.rb +144 -0
  91. data/pry-0.16.0/lib/pry/editor.rb +157 -0
  92. data/pry-0.16.0/lib/pry/env.rb +18 -0
  93. data/pry-0.16.0/lib/pry/exception_handler.rb +48 -0
  94. data/pry-0.16.0/lib/pry/exceptions.rb +73 -0
  95. data/pry-0.16.0/lib/pry/forwardable.rb +27 -0
  96. data/pry-0.16.0/lib/pry/helpers/base_helpers.rb +71 -0
  97. data/pry-0.16.0/lib/pry/helpers/command_helpers.rb +146 -0
  98. data/pry-0.16.0/lib/pry/helpers/documentation_helpers.rb +84 -0
  99. data/pry-0.16.0/lib/pry/helpers/options_helpers.rb +34 -0
  100. data/pry-0.16.0/lib/pry/helpers/platform.rb +55 -0
  101. data/pry-0.16.0/lib/pry/helpers/table.rb +121 -0
  102. data/pry-0.16.0/lib/pry/helpers/text.rb +118 -0
  103. data/pry-0.16.0/lib/pry/helpers.rb +8 -0
  104. data/pry-0.16.0/lib/pry/history.rb +153 -0
  105. data/pry-0.16.0/lib/pry/hooks.rb +180 -0
  106. data/pry-0.16.0/lib/pry/indent.rb +414 -0
  107. data/pry-0.16.0/lib/pry/input/simple_stdio.rb +13 -0
  108. data/pry-0.16.0/lib/pry/input_completer.rb +283 -0
  109. data/pry-0.16.0/lib/pry/input_lock.rb +129 -0
  110. data/pry-0.16.0/lib/pry/inspector.rb +39 -0
  111. data/pry-0.16.0/lib/pry/last_exception.rb +61 -0
  112. data/pry-0.16.0/lib/pry/method/disowned.rb +67 -0
  113. data/pry-0.16.0/lib/pry/method/patcher.rb +131 -0
  114. data/pry-0.16.0/lib/pry/method/weird_method_locator.rb +222 -0
  115. data/pry-0.16.0/lib/pry/method.rb +599 -0
  116. data/pry-0.16.0/lib/pry/object_path.rb +91 -0
  117. data/pry-0.16.0/lib/pry/output.rb +136 -0
  118. data/pry-0.16.0/lib/pry/pager.rb +249 -0
  119. data/pry-0.16.0/lib/pry/prompt.rb +214 -0
  120. data/pry-0.16.0/lib/pry/pry_class.rb +371 -0
  121. data/pry-0.16.0/lib/pry/pry_instance.rb +663 -0
  122. data/pry-0.16.0/lib/pry/repl.rb +326 -0
  123. data/pry-0.16.0/lib/pry/repl_file_loader.rb +79 -0
  124. data/pry-0.16.0/lib/pry/ring.rb +89 -0
  125. data/pry-0.16.0/lib/pry/slop/LICENSE +20 -0
  126. data/pry-0.16.0/lib/pry/slop/commands.rb +190 -0
  127. data/pry-0.16.0/lib/pry/slop/option.rb +210 -0
  128. data/pry-0.16.0/lib/pry/slop.rb +672 -0
  129. data/pry-0.16.0/lib/pry/syntax_highlighter.rb +26 -0
  130. data/pry-0.16.0/lib/pry/system_command_handler.rb +17 -0
  131. data/pry-0.16.0/lib/pry/testable/evalable.rb +24 -0
  132. data/pry-0.16.0/lib/pry/testable/mockable.rb +22 -0
  133. data/pry-0.16.0/lib/pry/testable/pry_tester.rb +88 -0
  134. data/pry-0.16.0/lib/pry/testable/utility.rb +34 -0
  135. data/pry-0.16.0/lib/pry/testable/variables.rb +52 -0
  136. data/pry-0.16.0/lib/pry/testable.rb +68 -0
  137. data/pry-0.16.0/lib/pry/version.rb +5 -0
  138. data/pry-0.16.0/lib/pry/warning.rb +20 -0
  139. data/pry-0.16.0/lib/pry/wrapped_module/candidate.rb +145 -0
  140. data/pry-0.16.0/lib/pry/wrapped_module.rb +382 -0
  141. data/pry-0.16.0/lib/pry.rb +148 -0
  142. data/super-smart-mod.gemspec +12 -0
  143. metadata +182 -0
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Helpers
5
+ # The methods defined on {Text} are available to custom commands via
6
+ # {Pry::Command#text}.
7
+ module Text
8
+ extend self
9
+
10
+ COLORS = {
11
+ "black" => 0,
12
+ "red" => 1,
13
+ "green" => 2,
14
+ "yellow" => 3,
15
+ "blue" => 4,
16
+ "purple" => 5,
17
+ "magenta" => 5,
18
+ "cyan" => 6,
19
+ "white" => 7
20
+ }.freeze
21
+
22
+ COLORS.each_pair do |color, value|
23
+ define_method color do |text|
24
+ "\033[0;#{30 + value}m#{text}\033[0m"
25
+ end
26
+
27
+ define_method "bright_#{color}" do |text|
28
+ "\033[1;#{30 + value}m#{text}\033[0m"
29
+ end
30
+
31
+ COLORS.each_pair do |bg_color, bg_value|
32
+ define_method "#{color}_on_#{bg_color}" do |text|
33
+ "\033[0;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
34
+ end
35
+
36
+ define_method "bright_#{color}_on_#{bg_color}" do |text|
37
+ "\033[1;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
38
+ end
39
+ end
40
+ end
41
+
42
+ # Remove any color codes from _text_.
43
+ #
44
+ # @param [String, #to_s] text
45
+ # @return [String] _text_ stripped of any color codes.
46
+ def strip_color(text)
47
+ text.to_s.gsub(/(\001)?(\e\[(\d[;\d]?)*m)(\002)?/, '')
48
+ end
49
+
50
+ # Returns _text_ as bold text for use on a terminal.
51
+ #
52
+ # @param [String, #to_s] text
53
+ # @return [String] _text_
54
+ def bold(text)
55
+ "\e[1m#{text}\e[0m"
56
+ end
57
+
58
+ # Returns `text` in the default foreground colour.
59
+ # Use this instead of "black" or "white" when you mean absence of colour.
60
+ #
61
+ # @param [String, #to_s] text
62
+ # @return [String]
63
+ def default(text)
64
+ text.to_s
65
+ end
66
+
67
+ #
68
+ # @yield
69
+ # Yields a block with color turned off.
70
+ #
71
+ # @return [void]
72
+ #
73
+ def no_color
74
+ boolean = Pry.config.color
75
+ Pry.config.color = false
76
+ yield
77
+ ensure
78
+ Pry.config.color = boolean
79
+ end
80
+
81
+ #
82
+ # @yield
83
+ # Yields a block with paging turned off.
84
+ #
85
+ # @return [void]
86
+ #
87
+ def no_pager
88
+ boolean = Pry.config.pager
89
+ Pry.config.pager = false
90
+ yield
91
+ ensure
92
+ Pry.config.pager = boolean
93
+ end
94
+
95
+ # Returns _text_ in a numbered list, beginning at _offset_.
96
+ #
97
+ # @param [#each_line] text
98
+ # @param [Fixnum] offset
99
+ # @return [String]
100
+ def with_line_numbers(text, offset, color = :blue)
101
+ lines = text.each_line.to_a
102
+ max_width = (offset + lines.count).to_s.length
103
+ lines.each_with_index.map do |line, index|
104
+ adjusted_index = (index + offset).to_s.rjust(max_width)
105
+ "#{send(color, adjusted_index)}: #{line}"
106
+ end.join
107
+ end
108
+
109
+ # Returns _text_ indented by _chars_ spaces.
110
+ #
111
+ # @param [String] text
112
+ # @param [Fixnum] chars
113
+ def indent(text, chars)
114
+ text.lines.map { |l| "#{' ' * chars}#{l}" }.join
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pry/helpers/base_helpers"
4
+ require "pry/helpers/options_helpers"
5
+ require "pry/helpers/command_helpers"
6
+ require "pry/helpers/text"
7
+ require "pry/helpers/table"
8
+ require "pry/helpers/platform"
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # The History class is responsible for maintaining the user's input history,
5
+ # both internally and within Readline.
6
+ class History
7
+ def self.default_file
8
+ history_file =
9
+ if (xdg_home = Pry::Env['XDG_DATA_HOME'])
10
+ # See XDG Base Directory Specification at
11
+ # https://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
12
+ xdg_home + '/pry/pry_history'
13
+ elsif File.exist?(File.expand_path('~/.pry_history'))
14
+ '~/.pry_history'
15
+ else
16
+ '~/.local/share/pry/pry_history'
17
+ end
18
+ File.expand_path(history_file)
19
+ end
20
+
21
+ attr_accessor :loader, :saver
22
+
23
+ # @return [Fixnum] Number of lines in history when Pry first loaded.
24
+ attr_reader :original_lines
25
+
26
+ # @return [Integer] total number of lines, including original lines
27
+ attr_reader :history_line_count
28
+
29
+ def initialize(options = {})
30
+ @history = options[:history] || []
31
+ @history_line_count = @history.count
32
+ @file_path = options[:file_path]
33
+ @original_lines = 0
34
+ @loader = method(:read_from_file)
35
+ @saver = method(:save_to_file)
36
+ end
37
+
38
+ # Load the input history using `History.loader`.
39
+ # @return [Integer] The number of lines loaded
40
+ def load
41
+ @loader.call do |line|
42
+ next if invalid_readline_line?(line)
43
+
44
+ @history << line.chomp
45
+ @original_lines += 1
46
+ @history_line_count += 1
47
+ end
48
+ end
49
+
50
+ # Add a line to the input history, ignoring blank and duplicate lines.
51
+ # @param [String] line
52
+ # @return [String] The same line that was passed in
53
+ def push(line)
54
+ return line if line.empty? || invalid_readline_line?(line)
55
+
56
+ begin
57
+ last_line = @history[-1]
58
+ rescue IndexError
59
+ last_line = nil
60
+ end
61
+
62
+ return line if line == last_line
63
+
64
+ @history << line
65
+ @history_line_count += 1
66
+ @saver.call(line) if !should_ignore?(line) && Pry.config.history_save
67
+
68
+ line
69
+ end
70
+ alias << push
71
+
72
+ # Clear this session's history. This won't affect the contents of the
73
+ # history file.
74
+ def clear
75
+ @history.clear
76
+ @history_line_count = 0
77
+ @original_lines = 0
78
+ end
79
+
80
+ # @return [Fixnum] The number of lines in history from just this session.
81
+ def session_line_count
82
+ @history_line_count - @original_lines
83
+ end
84
+
85
+ # Return an Array containing all stored history.
86
+ # @return [Array<String>] An Array containing all lines of history loaded
87
+ # or entered by the user in the current session.
88
+ def to_a
89
+ @history.to_a
90
+ end
91
+
92
+ # Filter the history with the histignore options
93
+ # @return [Array<String>] An array containing all the lines that are not
94
+ # included in the histignore.
95
+ def filter(history)
96
+ history.select { |l| l unless should_ignore?(l) }
97
+ end
98
+
99
+ private
100
+
101
+ # Check if the line match any option in the histignore
102
+ # [Pry.config.history_ignorelist]
103
+ # @return [Boolean] a boolean that notifies if the line was found in the
104
+ # histignore array.
105
+ def should_ignore?(line)
106
+ hist_ignore = Pry.config.history_ignorelist
107
+ return false if hist_ignore.nil? || hist_ignore.empty?
108
+
109
+ hist_ignore.any? { |p| line.to_s.match(p) }
110
+ end
111
+
112
+ # The default loader. Yields lines from `Pry.config.history_file`.
113
+ def read_from_file
114
+ path = history_file_path
115
+
116
+ File.foreach(path) { |line| yield(line) } if File.exist?(path)
117
+ rescue SystemCallError => error
118
+ warn "Unable to read history file: #{error.message}"
119
+ end
120
+
121
+ # The default saver. Appends the given line to `Pry.config.history_file`.
122
+ def save_to_file(line)
123
+ history_file.puts line if history_file
124
+ end
125
+
126
+ # The history file, opened for appending.
127
+ def history_file
128
+ if defined?(@history_file)
129
+ @history_file
130
+ else
131
+ unless File.exist?(history_file_path)
132
+ FileUtils.mkdir_p(File.dirname(history_file_path))
133
+ end
134
+ @history_file = File.open(history_file_path, 'a', 0o600).tap do |file|
135
+ file.sync = true
136
+ end
137
+ end
138
+ rescue SystemCallError => error
139
+ warn "Unable to write history file: #{error.message}"
140
+ @history_file = false
141
+ end
142
+
143
+ def history_file_path
144
+ File.expand_path(@file_path || Pry.config.history_file)
145
+ end
146
+
147
+ def invalid_readline_line?(line)
148
+ # `Readline::HISTORY << line` raises an `ArgumentError` if `line`
149
+ # includes a null byte
150
+ line.include?("\0")
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # Implements a hooks system for Pry. A hook is a callable that is associated
5
+ # with an event. A number of events are currently provided by Pry, these
6
+ # include: `:when_started`, `:before_session`, `:after_session`. A hook must
7
+ # have a name, and is connected with an event by the `Pry::Hooks#add_hook`
8
+ # method.
9
+ #
10
+ # @example Adding a hook for the `:before_session` event.
11
+ # Pry.config.hooks.add_hook(:before_session, :say_hi) do
12
+ # puts "hello"
13
+ # end
14
+ class Hooks
15
+ def self.default
16
+ hooks = new
17
+ hooks.add_hook(:before_session, :default) do |_out, _target, pry_instance|
18
+ next if pry_instance.quiet?
19
+
20
+ pry_instance.run_command('whereami --quiet')
21
+ end
22
+ hooks
23
+ end
24
+
25
+ def initialize
26
+ @hooks = Hash.new { |h, k| h[k] = [] }
27
+ end
28
+
29
+ # Ensure that duplicates have their @hooks object.
30
+ def initialize_copy(_orig)
31
+ hooks_dup = @hooks.dup
32
+ @hooks.each do |k, v|
33
+ hooks_dup[k] = v.dup
34
+ end
35
+
36
+ @hooks = hooks_dup
37
+ end
38
+
39
+ def errors
40
+ @errors ||= []
41
+ end
42
+
43
+ # Destructively merge the contents of two `Pry:Hooks` instances.
44
+ #
45
+ # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
46
+ # @return [Pry:Hooks] The receiver.
47
+ # @see #merge
48
+ def merge!(other)
49
+ @hooks.merge!(other.dup.hooks) do |_key, array, other_array|
50
+ temp_hash = {}
51
+ output = []
52
+
53
+ (array + other_array).reverse_each do |pair|
54
+ temp_hash[pair.first] ||= output.unshift(pair)
55
+ end
56
+
57
+ output
58
+ end
59
+
60
+ self
61
+ end
62
+
63
+ # @example
64
+ # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" }
65
+ # Pry::Hooks.new.merge(hooks)
66
+ # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
67
+ # @return [Pry::Hooks] a new `Pry::Hooks` instance containing a merge of the
68
+ # contents of two `Pry:Hooks` instances.
69
+ def merge(other)
70
+ dup.tap do |v|
71
+ v.merge!(other)
72
+ end
73
+ end
74
+
75
+ # Add a new hook to be executed for the `event_name` event.
76
+ # @param [Symbol] event_name The name of the event.
77
+ # @param [Symbol] hook_name The name of the hook.
78
+ # @param [#call] callable The callable.
79
+ # @yield The block to use as the callable (if no `callable` provided).
80
+ # @return [Pry:Hooks] The receiver.
81
+ def add_hook(event_name, hook_name, callable = nil, &block)
82
+ event_name = event_name.to_s
83
+
84
+ # do not allow duplicates, but allow multiple `nil` hooks
85
+ # (anonymous hooks)
86
+ if hook_exists?(event_name, hook_name) && !hook_name.nil?
87
+ raise ArgumentError, "Hook with name '#{hook_name}' already defined!"
88
+ end
89
+
90
+ raise ArgumentError, "Must provide a block or callable." if !block && !callable
91
+
92
+ # ensure we only have one anonymous hook
93
+ @hooks[event_name].delete_if { |h, _k| h.nil? } if hook_name.nil?
94
+
95
+ if block
96
+ @hooks[event_name] << [hook_name, block]
97
+ elsif callable
98
+ @hooks[event_name] << [hook_name, callable]
99
+ end
100
+
101
+ self
102
+ end
103
+
104
+ # Execute the list of hooks for the `event_name` event.
105
+ # @param [Symbol] event_name The name of the event.
106
+ # @param [Array] args The arguments to pass to each hook function.
107
+ # @return [Object] The return value of the last executed hook.
108
+ def exec_hook(event_name, *args, &block)
109
+ @hooks[event_name.to_s].map do |_hook_name, callable|
110
+ begin
111
+ callable.call(*args, &block)
112
+ rescue RescuableException => e
113
+ errors << e
114
+ e
115
+ end
116
+ end.last
117
+ end
118
+
119
+ # @param [Symbol] event_name The name of the event.
120
+ # @return [Fixnum] The number of hook functions for `event_name`.
121
+ def hook_count(event_name)
122
+ @hooks[event_name.to_s].size
123
+ end
124
+
125
+ # @param [Symbol] event_name The name of the event.
126
+ # @param [Symbol] hook_name The name of the hook
127
+ # @return [#call] a specific hook for a given event.
128
+ def get_hook(event_name, hook_name)
129
+ hook = @hooks[event_name.to_s].find do |current_hook_name, _callable|
130
+ current_hook_name == hook_name
131
+ end
132
+ hook.last if hook
133
+ end
134
+
135
+ # @param [Symbol] event_name The name of the event.
136
+ # @return [Hash] The hash of hook names / hook functions.
137
+ # @note Modifying the returned hash does not alter the hooks, use
138
+ # `add_hook`/`delete_hook` for that.
139
+ def get_hooks(event_name)
140
+ Hash[@hooks[event_name.to_s]]
141
+ end
142
+
143
+ # @param [Symbol] event_name The name of the event.
144
+ # @param [Symbol] hook_name The name of the hook.
145
+ # to delete.
146
+ # @return [#call] The deleted hook.
147
+ def delete_hook(event_name, hook_name)
148
+ deleted_callable = nil
149
+
150
+ @hooks[event_name.to_s].delete_if do |current_hook_name, callable|
151
+ if current_hook_name == hook_name
152
+ deleted_callable = callable
153
+ true
154
+ else
155
+ false
156
+ end
157
+ end
158
+ deleted_callable
159
+ end
160
+
161
+ # Clear all hooks functions for a given event.
162
+ #
163
+ # @param [String] event_name The name of the event.
164
+ # @return [void]
165
+ def clear_event_hooks(event_name)
166
+ @hooks[event_name.to_s] = []
167
+ end
168
+
169
+ # @param [Symbol] event_name Name of the event.
170
+ # @param [Symbol] hook_name Name of the hook.
171
+ # @return [Boolean] Whether the hook by the name `hook_name`.
172
+ def hook_exists?(event_name, hook_name)
173
+ @hooks[event_name.to_s].map(&:first).include?(hook_name)
174
+ end
175
+
176
+ protected
177
+
178
+ attr_reader :hooks
179
+ end
180
+ end