pry 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +162 -1
  3. data/LICENSE +1 -1
  4. data/README.md +331 -269
  5. data/bin/pry +5 -0
  6. data/lib/pry.rb +132 -119
  7. data/lib/pry/basic_object.rb +8 -4
  8. data/lib/pry/block_command.rb +22 -0
  9. data/lib/pry/class_command.rb +194 -0
  10. data/lib/pry/cli.rb +43 -51
  11. data/lib/pry/code.rb +40 -28
  12. data/lib/pry/code/code_file.rb +28 -24
  13. data/lib/pry/code/code_range.rb +4 -2
  14. data/lib/pry/code/loc.rb +15 -8
  15. data/lib/pry/code_object.rb +40 -38
  16. data/lib/pry/color_printer.rb +47 -46
  17. data/lib/pry/command.rb +166 -369
  18. data/lib/pry/command_set.rb +76 -73
  19. data/lib/pry/command_state.rb +31 -0
  20. data/lib/pry/commands/amend_line.rb +86 -81
  21. data/lib/pry/commands/bang.rb +18 -14
  22. data/lib/pry/commands/bang_pry.rb +15 -11
  23. data/lib/pry/commands/cat.rb +61 -54
  24. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  25. data/lib/pry/commands/cat/exception_formatter.rb +71 -60
  26. data/lib/pry/commands/cat/file_formatter.rb +55 -49
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  28. data/lib/pry/commands/cd.rb +40 -35
  29. data/lib/pry/commands/change_inspector.rb +29 -22
  30. data/lib/pry/commands/change_prompt.rb +44 -39
  31. data/lib/pry/commands/clear_screen.rb +16 -10
  32. data/lib/pry/commands/code_collector.rb +148 -133
  33. data/lib/pry/commands/disable_pry.rb +23 -19
  34. data/lib/pry/commands/easter_eggs.rb +19 -30
  35. data/lib/pry/commands/edit.rb +184 -161
  36. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  37. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  38. data/lib/pry/commands/exit.rb +39 -35
  39. data/lib/pry/commands/exit_all.rb +24 -20
  40. data/lib/pry/commands/exit_program.rb +20 -16
  41. data/lib/pry/commands/find_method.rb +168 -160
  42. data/lib/pry/commands/fix_indent.rb +16 -12
  43. data/lib/pry/commands/help.rb +140 -133
  44. data/lib/pry/commands/hist.rb +151 -150
  45. data/lib/pry/commands/import_set.rb +20 -16
  46. data/lib/pry/commands/jump_to.rb +25 -21
  47. data/lib/pry/commands/list_inspectors.rb +35 -28
  48. data/lib/pry/commands/ls.rb +124 -102
  49. data/lib/pry/commands/ls/constants.rb +59 -42
  50. data/lib/pry/commands/ls/formatter.rb +50 -46
  51. data/lib/pry/commands/ls/globals.rb +38 -34
  52. data/lib/pry/commands/ls/grep.rb +17 -13
  53. data/lib/pry/commands/ls/instance_vars.rb +29 -27
  54. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  55. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  56. data/lib/pry/commands/ls/local_names.rb +26 -22
  57. data/lib/pry/commands/ls/local_vars.rb +38 -28
  58. data/lib/pry/commands/ls/ls_entity.rb +47 -51
  59. data/lib/pry/commands/ls/methods.rb +44 -43
  60. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  61. data/lib/pry/commands/ls/self_methods.rb +23 -22
  62. data/lib/pry/commands/nesting.rb +21 -17
  63. data/lib/pry/commands/play.rb +93 -82
  64. data/lib/pry/commands/pry_backtrace.rb +22 -17
  65. data/lib/pry/commands/pry_version.rb +15 -11
  66. data/lib/pry/commands/raise_up.rb +27 -22
  67. data/lib/pry/commands/reload_code.rb +60 -48
  68. data/lib/pry/commands/reset.rb +16 -12
  69. data/lib/pry/commands/ri.rb +55 -45
  70. data/lib/pry/commands/save_file.rb +45 -43
  71. data/lib/pry/commands/shell_command.rb +51 -51
  72. data/lib/pry/commands/shell_mode.rb +21 -17
  73. data/lib/pry/commands/show_doc.rb +80 -68
  74. data/lib/pry/commands/show_info.rb +189 -171
  75. data/lib/pry/commands/show_input.rb +16 -11
  76. data/lib/pry/commands/show_source.rb +110 -45
  77. data/lib/pry/commands/stat.rb +35 -31
  78. data/lib/pry/commands/switch_to.rb +21 -15
  79. data/lib/pry/commands/toggle_color.rb +20 -16
  80. data/lib/pry/commands/watch_expression.rb +89 -86
  81. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  82. data/lib/pry/commands/whereami.rb +156 -148
  83. data/lib/pry/commands/wtf.rb +75 -50
  84. data/lib/pry/config.rb +307 -25
  85. data/lib/pry/config/attributable.rb +22 -0
  86. data/lib/pry/config/lazy_value.rb +29 -0
  87. data/lib/pry/config/memoized_value.rb +34 -0
  88. data/lib/pry/config/value.rb +24 -0
  89. data/lib/pry/control_d_handler.rb +28 -0
  90. data/lib/pry/core_extensions.rb +9 -7
  91. data/lib/pry/editor.rb +48 -21
  92. data/lib/pry/env.rb +18 -0
  93. data/lib/pry/exception_handler.rb +43 -0
  94. data/lib/pry/exceptions.rb +13 -16
  95. data/lib/pry/forwardable.rb +5 -1
  96. data/lib/pry/helpers.rb +2 -0
  97. data/lib/pry/helpers/base_helpers.rb +68 -197
  98. data/lib/pry/helpers/command_helpers.rb +50 -61
  99. data/lib/pry/helpers/documentation_helpers.rb +20 -13
  100. data/lib/pry/helpers/options_helpers.rb +14 -7
  101. data/lib/pry/helpers/platform.rb +7 -5
  102. data/lib/pry/helpers/table.rb +33 -26
  103. data/lib/pry/helpers/text.rb +17 -14
  104. data/lib/pry/history.rb +48 -56
  105. data/lib/pry/hooks.rb +21 -12
  106. data/lib/pry/indent.rb +54 -50
  107. data/lib/pry/input_completer.rb +248 -230
  108. data/lib/pry/input_lock.rb +8 -9
  109. data/lib/pry/inspector.rb +36 -24
  110. data/lib/pry/last_exception.rb +45 -45
  111. data/lib/pry/method.rb +141 -94
  112. data/lib/pry/method/disowned.rb +16 -4
  113. data/lib/pry/method/patcher.rb +12 -3
  114. data/lib/pry/method/weird_method_locator.rb +68 -44
  115. data/lib/pry/object_path.rb +33 -25
  116. data/lib/pry/output.rb +121 -35
  117. data/lib/pry/pager.rb +186 -180
  118. data/lib/pry/prompt.rb +123 -54
  119. data/lib/pry/pry_class.rb +61 -103
  120. data/lib/pry/pry_instance.rb +217 -215
  121. data/lib/pry/repl.rb +18 -22
  122. data/lib/pry/repl_file_loader.rb +27 -21
  123. data/lib/pry/ring.rb +11 -6
  124. data/lib/pry/slop.rb +574 -563
  125. data/lib/pry/slop/commands.rb +164 -169
  126. data/lib/pry/slop/option.rb +172 -168
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable.rb +59 -61
  130. data/lib/pry/testable/evalable.rb +21 -12
  131. data/lib/pry/testable/mockable.rb +18 -10
  132. data/lib/pry/testable/pry_tester.rb +71 -56
  133. data/lib/pry/testable/utility.rb +29 -21
  134. data/lib/pry/testable/variables.rb +49 -43
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +27 -0
  137. data/lib/pry/wrapped_module.rb +51 -42
  138. data/lib/pry/wrapped_module/candidate.rb +21 -14
  139. metadata +35 -35
  140. data/lib/pry/commands.rb +0 -6
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gem_readme.rb +0 -25
  147. data/lib/pry/commands/gem_search.rb +0 -40
  148. data/lib/pry/commands/gem_stats.rb +0 -83
  149. data/lib/pry/commands/gist.rb +0 -102
  150. data/lib/pry/commands/install_command.rb +0 -54
  151. data/lib/pry/config/behavior.rb +0 -255
  152. data/lib/pry/config/convenience.rb +0 -28
  153. data/lib/pry/config/default.rb +0 -159
  154. data/lib/pry/config/memoization.rb +0 -48
  155. data/lib/pry/platform.rb +0 -91
  156. data/lib/pry/plugins.rb +0 -122
  157. data/lib/pry/rubygem.rb +0 -84
  158. data/lib/pry/terminal.rb +0 -91
data/lib/pry/pry_class.rb CHANGED
@@ -1,17 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+ require 'pathname'
5
+
1
6
  class Pry
2
- HOME_RC_FILE =
3
- if ENV.key?('PRYRC')
4
- ENV['PRYRC']
5
- elsif File.exist?(File.expand_path('~/.pryrc'))
6
- '~/.pryrc'
7
- elsif ENV.key?('XDG_CONFIG_HOME') && ENV['XDG_CONFIG_HOME'] != ''
8
- # See XDG Base Directory Specification at
9
- # https://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
10
- ENV['XDG_CONFIG_HOME'] + '/pry/pryrc'
11
- else
12
- '~/.config/pry/pryrc'
13
- end
14
- LOCAL_RC_FILE = "./.pryrc"
7
+ LOCAL_RC_FILE = "./.pryrc".freeze
8
+
9
+ # @return [Boolean] true if this Ruby supports safe levels and tainting,
10
+ # to guard against using deprecated or unsupported features
11
+ HAS_SAFE_LEVEL = (
12
+ RUBY_ENGINE == 'ruby' &&
13
+ Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
14
+ )
15
15
 
16
16
  class << self
17
17
  extend Pry::Forwardable
@@ -23,24 +23,14 @@ class Pry
23
23
  attr_accessor :quiet
24
24
  attr_accessor :last_internal_error
25
25
  attr_accessor :config
26
- attr_writer :history
27
-
28
- def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
29
26
 
30
- extend Pry::Config::Convenience
31
- config_shortcut(*Pry::Config.shortcuts)
32
-
33
- def prompt=(value)
34
- config.prompt = value
35
- end
36
-
37
- def prompt
38
- config.prompt
39
- end
40
-
41
- def history
42
- @history ||= History.new
43
- end
27
+ def_delegators(
28
+ :@config, :input, :input=, :output, :output=, :commands,
29
+ :commands=, :print, :print=, :exception_handler, :exception_handler=,
30
+ :hooks, :hooks=, :color, :color=, :pager, :pager=, :editor, :editor=,
31
+ :memory_size, :memory_size=, :extra_sticky_locals, :extra_sticky_locals=,
32
+ :prompt, :prompt=, :history, :history=
33
+ )
44
34
 
45
35
  #
46
36
  # @example
@@ -71,7 +61,7 @@ class Pry
71
61
  # Returns a value store for an instance of Pry running on the current thread.
72
62
  #
73
63
  def self.current
74
- Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil)
64
+ Thread.current[:__pry__] ||= {}
75
65
  end
76
66
 
77
67
  # Load the given file in the context of `Pry.toplevel_binding`
@@ -82,8 +72,8 @@ class Pry
82
72
  puts "Error loading #{file}: #{e}\n#{e.backtrace.first}"
83
73
  end
84
74
 
85
- # Load HOME_RC_FILE and LOCAL_RC_FILE if appropriate
86
- # This method can also be used to reload the files if they have changed.
75
+ # Load RC files if appropriate This method can also be used to reload the
76
+ # files if they have changed.
87
77
  def self.load_rc_files
88
78
  rc_files_to_load.each do |file|
89
79
  critical_section do
@@ -95,7 +85,7 @@ class Pry
95
85
  # Load the local RC file (./.pryrc)
96
86
  def self.rc_files_to_load
97
87
  files = []
98
- files << HOME_RC_FILE if Pry.config.should_load_rc
88
+ files << Pry.config.rc_file if Pry.config.should_load_rc
99
89
  files << LOCAL_RC_FILE if Pry.config.should_load_local_rc
100
90
  files.map { |file| real_path_to(file) }.compact.uniq
101
91
  end
@@ -121,19 +111,17 @@ class Pry
121
111
  end
122
112
 
123
113
  def self.load_win32console
124
- begin
125
- require 'win32console'
126
- # The mswin and mingw versions of pry require win32console, so this should
127
- # only fail on jruby (where win32console doesn't work).
128
- # Instead we'll recommend ansicon, which does.
129
- rescue LoadError
130
- warn <<-WARNING if Pry.config.windows_console_warning
114
+ require 'win32console'
115
+ # The mswin and mingw versions of pry require win32console, so this should
116
+ # only fail on jruby (where win32console doesn't work).
117
+ # Instead we'll recommend ansicon, which does.
118
+ rescue LoadError
119
+ warn <<-WARNING if Pry.config.windows_console_warning
131
120
  For a better Pry experience on Windows, please use ansicon:
132
121
  https://github.com/adoxa/ansicon
133
122
  If you use an alternative to ansicon and don't want to see this warning again,
134
123
  you can add "Pry.config.windows_console_warning = false" to your pryrc.
135
- WARNING
136
- end
124
+ WARNING
137
125
  end
138
126
 
139
127
  # Do basic setup for initial session including: loading pryrc, plugins,
@@ -143,7 +131,7 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
143
131
 
144
132
  @initial_session = false
145
133
 
146
- # note these have to be loaded here rather than in pry_instance as
134
+ # note these have to be loaded here rather than in _pry_ as
147
135
  # we only want them loaded once per entire Pry lifetime.
148
136
  load_rc_files
149
137
  end
@@ -152,9 +140,8 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
152
140
  return if @session_finalized
153
141
 
154
142
  @session_finalized = true
155
- load_plugins if Pry.config.should_load_plugins
156
143
  load_requires if Pry.config.should_load_requires
157
- load_history if Pry.config.history.should_load
144
+ load_history if Pry.config.history_load
158
145
  load_traps if Pry.config.should_trap_interrupts
159
146
  load_win32console if Helpers::Platform.windows? && !Helpers::Platform.windows_ansi?
160
147
  end
@@ -167,8 +154,8 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
167
154
  # @example
168
155
  # Pry.start(Object.new, :input => MyInput.new)
169
156
  def self.start(target = nil, options = {})
170
- return if ENV['DISABLE_PRY']
171
- if ENV['FAIL_PRY']
157
+ return if Pry::Env['DISABLE_PRY']
158
+ if Pry::Env['FAIL_PRY']
172
159
  raise 'You have FAIL_PRY set to true, which results in Pry calls failing'
173
160
  end
174
161
 
@@ -176,7 +163,8 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
176
163
 
177
164
  if in_critical_section?
178
165
  output.puts "ERROR: Pry started inside Pry."
179
- output.puts "This can happen if you have a binding.pry inside a #to_s or #inspect function."
166
+ output.puts "This can happen if you have a binding.pry inside a #to_s " \
167
+ "or #inspect function."
180
168
  return
181
169
  end
182
170
 
@@ -206,7 +194,6 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
206
194
  # Execute the file through the REPL loop, non-interactively.
207
195
  # @param [String] file_name File name to load through the REPL.
208
196
  def self.load_file_through_repl(file_name)
209
- require "pry/repl_file_loader"
210
197
  REPLFileLoader.new(file_name).load
211
198
  end
212
199
 
@@ -232,17 +219,23 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
232
219
  def self.view_clip(obj, options = {})
233
220
  max = options.fetch :max_length, 60
234
221
  id = options.fetch :id, false
235
- if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max
222
+ if obj.is_a?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max
236
223
  obj.name.to_s
237
224
  elsif Pry.main == obj
238
- # special-case to support jruby.
239
- # fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
225
+ # Special-case to support jruby. Fixed as of:
226
+ # https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
240
227
  # we can drop in the future.
241
228
  obj.to_s
242
- elsif Pry.config.prompt_safe_contexts.any? { |v| v === obj } && obj.inspect.length <= max
229
+ # rubocop:disable Style/CaseEquality
230
+ elsif Pry.config.prompt_safe_contexts.any? { |v| v === obj } &&
231
+ obj.inspect.length <= max
232
+ # rubocop:enable Style/CaseEquality
233
+
243
234
  obj.inspect
235
+ elsif id
236
+ format("#<#{obj.class}:0x%<id>x>", id: obj.object_id << 1)
244
237
  else
245
- id == true ? "#<#{obj.class}:0x%x>" % (obj.object_id << 1) : "#<#{obj.class}>"
238
+ "#<#{obj.class}>"
246
239
  end
247
240
  rescue RescuableException
248
241
  "unknown"
@@ -292,16 +285,6 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
292
285
  nil
293
286
  end
294
287
 
295
- def self.default_editor_for_platform
296
- return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty?
297
- return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty?
298
- return 'notepad' if Helpers::Platform.windows?
299
-
300
- %w(editor nano vi).detect do |editor|
301
- system("which #{editor} > /dev/null 2>&1")
302
- end
303
- end
304
-
305
288
  def self.auto_resize!
306
289
  Pry.config.input # by default, load Readline
307
290
 
@@ -311,23 +294,23 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
311
294
  end
312
295
 
313
296
  if Readline::VERSION =~ /edit/i
314
- warn <<-EOT
297
+ warn(<<-WARN)
315
298
  Readline version #{Readline::VERSION} detected - will not auto_resize! correctly.
316
299
  For the fix, use GNU Readline instead:
317
- https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X
318
- EOT
300
+ https://github.com/guard/guard/wiki/Add-Readline-support-to-Ruby-on-Mac-OS-X
301
+ WARN
319
302
  return
320
303
  end
321
304
 
322
305
  trap :WINCH do
323
306
  begin
324
- Readline.set_screen_size(*Terminal.size!)
325
- rescue => e
307
+ Readline.set_screen_size(*output.size)
308
+ rescue StandardError => e
326
309
  warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}"
327
310
  end
328
311
  begin
329
312
  Readline.refresh_line
330
- rescue => e
313
+ rescue StandardError => e
331
314
  warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}"
332
315
  end
333
316
  end
@@ -338,7 +321,7 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
338
321
  @initial_session = true
339
322
  @session_finalized = nil
340
323
 
341
- self.config = Pry::Config.new Pry::Config::Default.new
324
+ self.config = Pry::Config.new
342
325
  self.cli = false
343
326
  self.current_line = 1
344
327
  self.line_buffer = [""]
@@ -347,9 +330,7 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
347
330
 
348
331
  # Basic initialization.
349
332
  def self.init
350
- @plugin_manager ||= PluginManager.new
351
333
  reset_defaults
352
- locate_plugins
353
334
  end
354
335
 
355
336
  # Return a `Binding` object for `target` or return `target` if it is
@@ -358,15 +339,10 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
358
339
  # @param [Object] target The object to get a `Binding` object for.
359
340
  # @return [Binding] The `Binding` object.
360
341
  def self.binding_for(target)
361
- if Binding === target
362
- target
363
- else
364
- if Pry.main == target
365
- TOPLEVEL_BINDING
366
- else
367
- target.__binding__
368
- end
369
- end
342
+ return target if Binding === target # rubocop:disable Style/CaseEquality
343
+ return TOPLEVEL_BINDING if Pry.main == target
344
+
345
+ target.__binding__
370
346
  end
371
347
 
372
348
  def self.toplevel_binding
@@ -386,8 +362,8 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
386
362
  @toplevel_binding
387
363
  end
388
364
 
389
- def self.toplevel_binding=(binding)
390
- @toplevel_binding = binding
365
+ class << self
366
+ attr_writer :toplevel_binding
391
367
  end
392
368
 
393
369
  def self.in_critical_section?
@@ -402,24 +378,6 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
402
378
  ensure
403
379
  Thread.current[:pry_critical_section] -= 1
404
380
  end
405
-
406
- # Wraps a block in a named block called `Pry::Config::Lazy`. This is used for
407
- # dynamic config values, which are calculated every time
408
- # {Pry::Config::Lazy#call} is called.
409
- #
410
- # @example
411
- # # pryrc
412
- # Pry.config.prompt_name = Pry.lazy { rand(100) }
413
- #
414
- # # Session
415
- # [1] 96(main)>
416
- # [2] 19(main)>
417
- # [3] 80(main)>
418
- #
419
- # @return [#call]
420
- def self.lazy(&block)
421
- Pry::Config::Lazy.new(&block)
422
- end
423
381
  end
424
382
 
425
383
  Pry.init
@@ -1,4 +1,8 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
3
+ require 'method_source'
4
+ require 'ostruct'
5
+
2
6
  ##
3
7
  # Pry is a powerful alternative to the standard IRB shell for Ruby. It
4
8
  # features syntax highlighting, a flexible plugin architecture, runtime
@@ -23,6 +27,8 @@
23
27
 
24
28
  # rubocop:disable Metrics/ClassLength
25
29
  class Pry
30
+ extend Pry::Forwardable
31
+
26
32
  attr_accessor :binding_stack
27
33
  attr_accessor :custom_completions
28
34
  attr_accessor :eval_string
@@ -33,7 +39,6 @@ class Pry
33
39
  attr_accessor :last_dir
34
40
 
35
41
  attr_reader :last_exception
36
- attr_reader :command_state
37
42
  attr_reader :exit_value
38
43
 
39
44
  # @since v0.12.0
@@ -44,8 +49,13 @@ class Pry
44
49
 
45
50
  attr_reader :config
46
51
 
47
- extend Pry::Config::Convenience
48
- config_shortcut(*Pry::Config.shortcuts)
52
+ def_delegators(
53
+ :@config, :input, :input=, :output, :output=, :commands,
54
+ :commands=, :print, :print=, :exception_handler, :exception_handler=,
55
+ :hooks, :hooks=, :color, :color=, :pager, :pager=, :editor, :editor=,
56
+ :memory_size, :memory_size=, :extra_sticky_locals, :extra_sticky_locals=
57
+ )
58
+
49
59
  EMPTY_COMPLETIONS = [].freeze
50
60
 
51
61
  # Create a new {Pry} instance.
@@ -58,7 +68,7 @@ class Pry
58
68
  # The object to use for commands.
59
69
  # @option options [Hash] :hooks
60
70
  # The defined hook Procs.
61
- # @option options [Array<Proc>] :prompt
71
+ # @option options [Pry::Prompt] :prompt
62
72
  # The array of Procs to use for prompts.
63
73
  # @option options [Proc] :print
64
74
  # The Proc to use for printing return values.
@@ -70,13 +80,11 @@ class Pry
70
80
  # The initial context for this session.
71
81
  def initialize(options = {})
72
82
  @binding_stack = []
73
- @indent = Pry::Indent.new
74
- @command_state = {}
75
- @eval_string = ""
83
+ @indent = Pry::Indent.new(self)
84
+ @eval_string = ''.dup
76
85
  @backtrace = options.delete(:backtrace) || caller
77
86
  target = options.delete(:target)
78
- @config = Pry::Config.new
79
- config.merge!(options)
87
+ @config = self.class.config.merge(options)
80
88
  push_prompt(config.prompt)
81
89
  @input_ring = Pry::Ring.new(config.memory_size)
82
90
  @output_ring = Pry::Ring.new(config.memory_size)
@@ -85,44 +93,18 @@ class Pry
85
93
  @input_ring << nil
86
94
  push_initial_binding(target)
87
95
  exec_hook(:when_started, target, options, self)
88
- end
89
-
90
- @input_array_warn = false
91
- # @deprecated Use {#input_ring} instead.
92
- def input_array
93
- unless @input_array_warn
94
- loc = caller_locations(1..1).first
95
- warn(
96
- "#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
97
- "is deprecated. Use #{self.class}#input_ring instead"
98
- )
99
- @input_array_warn = true
100
- end
101
-
102
- @input_ring
103
- end
104
-
105
- @output_array_warn = false
106
- # @deprecated Use {#output_ring} instead.
107
- def output_array
108
- unless @output_array_warn
109
- loc = caller_locations(1..1).first
110
- warn(
111
- "#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
112
- "is deprecated. Use #{self.class}#output_ring instead"
113
- )
114
- @output_array_warn = true
115
- end
116
-
117
- @output_ring
96
+ @prompt_warn = false
118
97
  end
119
98
 
120
99
  # This is the prompt at the top of the prompt stack.
121
- # @return [Array<Proc>] the current prompt
100
+ # @return [Pry::Prompt] the current prompt
122
101
  def prompt
123
102
  prompt_stack.last
124
103
  end
125
104
 
105
+ # Sets the Pry prompt.
106
+ # @param [Pry::Prompt] new_prompt
107
+ # @return [void]
126
108
  def prompt=(new_prompt)
127
109
  if prompt_stack.empty?
128
110
  push_prompt new_prompt
@@ -165,7 +147,11 @@ class Pry
165
147
 
166
148
  Pry.critical_section do
167
149
  completer = config.completer.new(config.input, self)
168
- completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys)
150
+ completer.call(
151
+ str,
152
+ target: current_binding,
153
+ custom_completions: custom_completions.call.push(*sticky_locals.keys)
154
+ )
169
155
  end
170
156
  end
171
157
 
@@ -178,20 +164,20 @@ class Pry
178
164
  # @param [Object] value
179
165
  # The value to set the local to.
180
166
  #
181
- # @param [Binding] b
167
+ # @param [Binding] binding
182
168
  # The binding to set the local on.
183
169
  #
184
170
  # @return [Object]
185
171
  # The value the local was set to.
186
172
  #
187
- def inject_local(name, value, b)
188
- value = Proc === value ? value.call : value
189
- if b.respond_to?(:local_variable_set)
190
- b.local_variable_set name, value
173
+ def inject_local(name, value, binding)
174
+ value = value.is_a?(Proc) ? value.call : value
175
+ if binding.respond_to?(:local_variable_set)
176
+ binding.local_variable_set name, value
191
177
  else # < 2.1
192
178
  begin
193
179
  Pry.current[:pry_local] = value
194
- b.eval "#{name} = ::Pry.current[:pry_local]"
180
+ binding.eval "#{name} = ::Pry.current[:pry_local]"
195
181
  ensure
196
182
  Pry.current[:pry_local] = nil
197
183
  end
@@ -228,9 +214,10 @@ class Pry
228
214
  end
229
215
 
230
216
  def sticky_locals
231
- { _in_: input_ring,
217
+ {
218
+ _in_: input_ring,
232
219
  _out_: output_ring,
233
- _pry_: self,
220
+ pry_instance: self,
234
221
  _ex_: last_exception && last_exception.wrapped_exception,
235
222
  _file_: last_file,
236
223
  _dir_: last_dir,
@@ -242,7 +229,7 @@ class Pry
242
229
  # Reset the current eval string. If the user has entered part of a multiline
243
230
  # expression, this discards that input.
244
231
  def reset_eval_string
245
- @eval_string = ""
232
+ @eval_string = ''.dup
246
233
  end
247
234
 
248
235
  # Pass a line of input to Pry.
@@ -273,7 +260,7 @@ class Pry
273
260
  exit_value = catch(:breakout) do
274
261
  handle_line(line, options)
275
262
  # We use 'return !@stopped' here instead of 'return true' so that if
276
- # handle_line has stopped this pry instance (e.g. by opening _pry_.repl and
263
+ # handle_line has stopped this pry instance (e.g. by opening pry_instance.repl and
277
264
  # then popping all the bindings) we still exit immediately.
278
265
  return !@stopped
279
266
  end
@@ -286,94 +273,10 @@ class Pry
286
273
  # TODO: make this configurable?
287
274
  raise exception if exception
288
275
 
289
- return false
290
- end
291
-
292
- def handle_line(line, options)
293
- if line.nil?
294
- config.control_d_handler.call(@eval_string, self)
295
- return
296
- end
297
-
298
- ensure_correct_encoding!(line)
299
- Pry.history << line unless options[:generated]
300
-
301
- @suppress_output = false
302
- inject_sticky_locals!
303
- begin
304
- if !process_command_safely(line)
305
- @eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
306
- end
307
- rescue RescuableException => e
308
- self.last_exception = e
309
- result = e
310
-
311
- Pry.critical_section do
312
- show_result(result)
313
- end
314
- return
315
- end
316
-
317
- # This hook is supposed to be executed after each line of ruby code
318
- # has been read (regardless of whether eval_string is yet a complete expression)
319
- exec_hook :after_read, eval_string, self
320
-
321
- begin
322
- complete_expr = Pry::Code.complete_expression?(@eval_string)
323
- rescue SyntaxError => e
324
- output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}"
325
- reset_eval_string
326
- end
327
-
328
- if complete_expr
329
- if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/
330
- @suppress_output = true
331
- end
332
-
333
- # A bug in jruby makes java.lang.Exception not rescued by
334
- # `rescue Pry::RescuableException` clause.
335
- #
336
- # * https://github.com/pry/pry/issues/854
337
- # * https://jira.codehaus.org/browse/JRUBY-7100
338
- #
339
- # Until that gets fixed upstream, treat java.lang.Exception
340
- # as an additional exception to be rescued explicitly.
341
- #
342
- # This workaround has a side effect: java exceptions specified
343
- # in `Pry.config.exception_whitelist` are ignored.
344
- jruby_exceptions = []
345
- if Helpers::Platform.jruby?
346
- jruby_exceptions << Java::JavaLang::Exception
347
- end
348
-
349
- begin
350
- # Reset eval string, in case we're evaluating Ruby that does something
351
- # like open a nested REPL on this instance.
352
- eval_string = @eval_string
353
- reset_eval_string
354
-
355
- result = evaluate_ruby(eval_string)
356
- rescue RescuableException, *jruby_exceptions => e
357
- # Eliminate following warning:
358
- # warning: singleton on non-persistent Java type X
359
- # (http://wiki.jruby.org/Persistence)
360
- if Helpers::Platform.jruby? && e.class.respond_to?('__persistent__')
361
- e.class.__persistent__ = true
362
- end
363
- self.last_exception = e
364
- result = e
365
- end
366
-
367
- Pry.critical_section do
368
- show_result(result)
369
- end
370
- end
371
-
372
- throw(:breakout) if current_binding.nil?
276
+ false
373
277
  end
374
- private :handle_line
375
278
 
376
- # Potentially deprecated Use `Pry::REPL.new(pry, :target => target).start`
279
+ # Potentially deprecated. Use `Pry::REPL.new(pry, :target => target).start`
377
280
  # (If nested sessions are going to exist, this method is fine, but a goal is
378
281
  # to come up with an alternative to nested sessions altogether.)
379
282
  def repl(target = nil)
@@ -397,8 +300,6 @@ class Pry
397
300
  exception_handler.call(output, result, self)
398
301
  elsif should_print?
399
302
  print.call(output, result, self)
400
- else
401
- # nothin'
402
303
  end
403
304
  rescue RescuableException => e
404
305
  # Being uber-paranoid here, given that this exception arose because we couldn't
@@ -406,7 +307,7 @@ class Pry
406
307
  # the exception either.
407
308
  begin
408
309
  output.puts "(pry) output error: #{e.inspect}\n#{e.backtrace.join("\n")}"
409
- rescue RescuableException => e
310
+ rescue RescuableException
410
311
  if last_result_is_exception?
411
312
  output.puts "(pry) output error: failed to show exception"
412
313
  else
@@ -417,16 +318,6 @@ class Pry
417
318
  output.flush if output.respond_to?(:flush)
418
319
  end
419
320
 
420
- # Force `eval_string` into the encoding of `val`. [Issue #284]
421
- def ensure_correct_encoding!(val)
422
- if @eval_string.empty? &&
423
- val.respond_to?(:encoding) &&
424
- val.encoding != @eval_string.encoding
425
- @eval_string.force_encoding(val.encoding)
426
- end
427
- end
428
- private :ensure_correct_encoding!
429
-
430
321
  # If the given line is a valid command, process it in the context of the
431
322
  # current `eval_string` and binding.
432
323
  # @param [String] val The line to process.
@@ -434,7 +325,8 @@ class Pry
434
325
  def process_command(val)
435
326
  val = val.lstrip if /^\s\S/ !~ val
436
327
  val = val.chomp
437
- result = commands.process_line(val,
328
+ result = commands.process_line(
329
+ val,
438
330
  target: current_binding,
439
331
  output: output,
440
332
  eval_string: @eval_string,
@@ -449,11 +341,11 @@ class Pry
449
341
  # command was matched and invoked then `result.command?` returns true,
450
342
  # otherwise it returns false.
451
343
  if result.command?
452
- if !result.void_command?
344
+ unless result.void_command?
453
345
  # the command that was invoked was non-void (had a return value) and so we make
454
346
  # the value of the current expression equal to the return value
455
347
  # of the command.
456
- @eval_string.replace "::Pry.current[:pry_cmd_result].retval\n"
348
+ @eval_string = "::Pry.current[:pry_cmd_result].retval\n"
457
349
  end
458
350
  true
459
351
  else
@@ -467,7 +359,9 @@ class Pry
467
359
  # @return [Boolean] `true` if `val` is a command, `false` otherwise
468
360
  def process_command_safely(val)
469
361
  process_command(val)
470
- rescue CommandError, Pry::Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
362
+ rescue CommandError,
363
+ Pry::Slop::InvalidOptionError,
364
+ MethodSource::SourceNotFoundError => e
471
365
  Pry.last_internal_error = e
472
366
  output.puts "Error: #{e.message}"
473
367
  true
@@ -479,7 +373,8 @@ class Pry
479
373
  # @example
480
374
  # pry_instance.run_command("ls -m")
481
375
  def run_command(val)
482
- commands.process_line(val,
376
+ commands.process_line(
377
+ val,
483
378
  eval_string: @eval_string,
484
379
  target: current_binding,
485
380
  pry_instance: self,
@@ -501,8 +396,8 @@ class Pry
501
396
  hooks.exec_hook(name, *args, &block).tap do
502
397
  hooks.errors[e_before..-1].each do |e|
503
398
  output.puts "#{name} hook failed: #{e.class}: #{e.message}"
504
- output.puts "#{e.backtrace.first}"
505
- output.puts "(see _pry_.hooks.errors to debug)"
399
+ output.puts e.backtrace.first.to_s
400
+ output.puts "(see pry_instance.hooks.errors to debug)"
506
401
  end
507
402
  end
508
403
  end
@@ -518,15 +413,11 @@ class Pry
518
413
  self.last_result = result unless code =~ /\A\s*\z/
519
414
  end
520
415
 
521
- #
522
416
  # Set the last exception for a session.
523
- #
524
- # @param [Exception] e
525
- # the last exception.
526
- #
527
- def last_exception=(e)
528
- last_exception = Pry::LastException.new(e)
417
+ # @param [Exception] exception The last exception.
418
+ def last_exception=(exception)
529
419
  @last_result_is_exception = true
420
+ last_exception = Pry::LastException.new(exception)
530
421
  @output_ring << last_exception
531
422
  @last_exception = last_exception
532
423
  end
@@ -537,10 +428,10 @@ class Pry
537
428
  def update_input_history(code)
538
429
  # Always push to the @input_ring as the @output_ring is always pushed to.
539
430
  @input_ring << code
540
- if code
541
- Pry.line_buffer.push(*code.each_line)
542
- Pry.current_line += code.lines.count
543
- end
431
+ return unless code
432
+
433
+ Pry.line_buffer.push(*code.each_line)
434
+ Pry.current_line += code.lines.count
544
435
  end
545
436
 
546
437
  # @return [Boolean] True if the last result is an exception that was raised,
@@ -563,21 +454,37 @@ class Pry
563
454
  object = current_binding.eval('self')
564
455
  open_token = @indent.open_delimiters.last || @indent.stack.last
565
456
 
566
- c = Pry::Config.assign({
567
- object: object,
568
- nesting_level: binding_stack.size - 1,
569
- open_token: open_token,
570
- session_line: Pry.history.session_line_count + 1,
571
- history_line: Pry.history.history_line_count + 1,
572
- expr_number: input_ring.count,
573
- _pry_: self,
574
- binding_stack: binding_stack,
575
- input_ring: input_ring,
576
- eval_string: @eval_string,
577
- cont: !@eval_string.empty?
578
- })
457
+ c = OpenStruct.new(
458
+ object: object,
459
+ nesting_level: binding_stack.size - 1,
460
+ open_token: open_token,
461
+ session_line: Pry.history.session_line_count + 1,
462
+ history_line: Pry.history.history_line_count + 1,
463
+ expr_number: input_ring.count,
464
+ pry_instance: self,
465
+ binding_stack: binding_stack,
466
+ input_ring: input_ring,
467
+ eval_string: @eval_string,
468
+ cont: !@eval_string.empty?
469
+ )
579
470
 
580
471
  Pry.critical_section do
472
+ # If input buffer is empty, then use normal prompt. Otherwise use the wait
473
+ # prompt (indicating multi-line expression).
474
+ if prompt.is_a?(Pry::Prompt)
475
+ prompt_proc = eval_string.empty? ? prompt.wait_proc : prompt.incomplete_proc
476
+ return prompt_proc.call(c.object, c.nesting_level, c.pry_instance)
477
+ end
478
+
479
+ unless @prompt_warn
480
+ @prompt_warn = true
481
+ Kernel.warn(
482
+ "warning: setting prompt with help of " \
483
+ "`Pry.config.prompt = [proc {}, proc {}]` is deprecated. " \
484
+ "Use Pry::Prompt API instead"
485
+ )
486
+ end
487
+
581
488
  # If input buffer is empty then use normal prompt
582
489
  if eval_string.empty?
583
490
  generate_prompt(Array(prompt).first, c)
@@ -588,44 +495,30 @@ class Pry
588
495
  end
589
496
  end
590
497
 
591
- def generate_prompt(prompt_proc, conf)
592
- if prompt_proc.arity == 1
593
- prompt_proc.call(conf)
594
- else
595
- prompt_proc.call(conf.object, conf.nesting_level, conf._pry_)
596
- end
597
- end
598
- private :generate_prompt
599
-
600
- # the array that the prompt stack is stored in
601
- def prompt_stack
602
- @prompt_stack ||= Array.new
603
- end
604
- private :prompt_stack
605
-
606
498
  # Pushes the current prompt onto a stack that it can be restored from later.
607
499
  # Use this if you wish to temporarily change the prompt.
608
- # @param [Array<Proc>] new_prompt
609
- # @return [Array<Proc>] new_prompt
500
+ #
610
501
  # @example
611
- # new_prompt = [ proc { '>' }, proc { '>>' } ]
612
- # push_prompt(new_prompt) # => new_prompt
502
+ # push_prompt(Pry::Prompt[:my_prompt])
503
+ #
504
+ # @param [Pry::Prompt] new_prompt
505
+ # @return [Pry::Prompt] new_prompt
613
506
  def push_prompt(new_prompt)
614
507
  prompt_stack.push new_prompt
615
508
  end
616
509
 
617
- # Pops the current prompt off of the prompt stack.
618
- # If the prompt you are popping is the last prompt, it will not be popped.
619
- # Use this to restore the previous prompt.
620
- # @return [Array<Proc>] Prompt being popped.
510
+ # Pops the current prompt off of the prompt stack. If the prompt you are
511
+ # popping is the last prompt, it will not be popped. Use this to restore the
512
+ # previous prompt.
513
+ #
621
514
  # @example
622
- # prompt1 = [ proc { '>' }, proc { '>>' } ]
623
- # prompt2 = [ proc { '$' }, proc { '>' } ]
624
- # pry = Pry.new :prompt => prompt1
625
- # pry.push_prompt(prompt2)
515
+ # pry = Pry.new(prompt: Pry::Prompt[:my_prompt1])
516
+ # pry.push_prompt(Pry::Prompt[:my_prompt2])
626
517
  # pry.pop_prompt # => prompt2
627
518
  # pry.pop_prompt # => prompt1
628
519
  # pry.pop_prompt # => prompt1
520
+ #
521
+ # @return [Pry::Prompt] the prompt being popped
629
522
  def pop_prompt
630
523
  prompt_stack.size > 1 ? prompt_stack.pop : prompt
631
524
  end
@@ -633,7 +526,7 @@ class Pry
633
526
  undef :pager if method_defined? :pager
634
527
  # Returns the currently configured pager
635
528
  # @example
636
- # _pry_.pager.page text
529
+ # pry_instance.pager.page text
637
530
  def pager
638
531
  Pry::Pager.new(self)
639
532
  end
@@ -641,7 +534,7 @@ class Pry
641
534
  undef :output if method_defined? :output
642
535
  # Returns an output device
643
536
  # @example
644
- # _pry_.output.puts "ohai!"
537
+ # pry_instance.output.puts "ohai!"
645
538
  def output
646
539
  Pry::Output.new(self)
647
540
  end
@@ -667,7 +560,7 @@ class Pry
667
560
  raise ArgumentError, "wrong number of arguments"
668
561
  elsif !args.first.respond_to?(:exception)
669
562
  raise TypeError, "exception class/object expected"
670
- elsif args.length === 1
563
+ elsif args.size == 1
671
564
  args.first.exception
672
565
  else
673
566
  args.first.exception(args[1])
@@ -675,7 +568,7 @@ class Pry
675
568
 
676
569
  raise TypeError, "exception object expected" unless exception.is_a? Exception
677
570
 
678
- exception.set_backtrace(args.length === 3 ? args[2] : caller(1))
571
+ exception.set_backtrace(args.size == 3 ? args[2] : caller(1))
679
572
 
680
573
  if force || binding_stack.one?
681
574
  binding_stack.clear
@@ -686,14 +579,123 @@ class Pry
686
579
  end
687
580
  end
688
581
 
689
- def raise_up(*args); raise_up_common(false, *args); end
582
+ def raise_up(*args)
583
+ raise_up_common(false, *args)
584
+ end
690
585
 
691
- def raise_up!(*args); raise_up_common(true, *args); end
586
+ def raise_up!(*args)
587
+ raise_up_common(true, *args)
588
+ end
692
589
 
693
590
  # Convenience accessor for the `quiet` config key.
694
591
  # @return [Boolean]
695
592
  def quiet?
696
593
  config.quiet
697
594
  end
595
+
596
+ private
597
+
598
+ def handle_line(line, options)
599
+ if line.nil?
600
+ config.control_d_handler.call(self)
601
+ return
602
+ end
603
+
604
+ ensure_correct_encoding!(line)
605
+ Pry.history << line unless options[:generated]
606
+
607
+ @suppress_output = false
608
+ inject_sticky_locals!
609
+ begin
610
+ unless process_command_safely(line)
611
+ @eval_string += "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
612
+ end
613
+ rescue RescuableException => e
614
+ self.last_exception = e
615
+ result = e
616
+
617
+ Pry.critical_section do
618
+ show_result(result)
619
+ end
620
+ return
621
+ end
622
+
623
+ # This hook is supposed to be executed after each line of ruby code
624
+ # has been read (regardless of whether eval_string is yet a complete expression)
625
+ exec_hook :after_read, eval_string, self
626
+
627
+ begin
628
+ complete_expr = Pry::Code.complete_expression?(@eval_string)
629
+ rescue SyntaxError => e
630
+ output.puts e.message.gsub(/^.*syntax error, */, "SyntaxError: ")
631
+ reset_eval_string
632
+ end
633
+
634
+ if complete_expr
635
+ if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/
636
+ @suppress_output = true
637
+ end
638
+
639
+ # A bug in jruby makes java.lang.Exception not rescued by
640
+ # `rescue Pry::RescuableException` clause.
641
+ #
642
+ # * https://github.com/pry/pry/issues/854
643
+ # * https://jira.codehaus.org/browse/JRUBY-7100
644
+ #
645
+ # Until that gets fixed upstream, treat java.lang.Exception
646
+ # as an additional exception to be rescued explicitly.
647
+ #
648
+ # This workaround has a side effect: java exceptions specified
649
+ # in `Pry.config.unrescued_exceptions` are ignored.
650
+ jruby_exceptions = []
651
+ jruby_exceptions << Java::JavaLang::Exception if Helpers::Platform.jruby?
652
+
653
+ begin
654
+ # Reset eval string, in case we're evaluating Ruby that does something
655
+ # like open a nested REPL on this instance.
656
+ eval_string = @eval_string
657
+ reset_eval_string
658
+
659
+ result = evaluate_ruby(eval_string)
660
+ rescue RescuableException, *jruby_exceptions => e
661
+ # Eliminate following warning:
662
+ # warning: singleton on non-persistent Java type X
663
+ # (http://wiki.jruby.org/Persistence)
664
+ if Helpers::Platform.jruby? && e.class.respond_to?('__persistent__')
665
+ e.class.__persistent__ = true
666
+ end
667
+ self.last_exception = e
668
+ result = e
669
+ end
670
+
671
+ Pry.critical_section do
672
+ show_result(result)
673
+ end
674
+ end
675
+
676
+ throw(:breakout) if current_binding.nil?
677
+ end
678
+
679
+ # Force `eval_string` into the encoding of `val`. [Issue #284]
680
+ def ensure_correct_encoding!(val)
681
+ if @eval_string.empty? &&
682
+ val.respond_to?(:encoding) &&
683
+ val.encoding != @eval_string.encoding
684
+ @eval_string.force_encoding(val.encoding)
685
+ end
686
+ end
687
+
688
+ def generate_prompt(prompt_proc, conf)
689
+ if prompt_proc.arity == 1
690
+ prompt_proc.call(conf)
691
+ else
692
+ prompt_proc.call(conf.object, conf.nesting_level, conf.pry_instance)
693
+ end
694
+ end
695
+
696
+ # the array that the prompt stack is stored in
697
+ def prompt_stack
698
+ @prompt_stack ||= []
699
+ end
698
700
  end
699
701
  # rubocop:enable Metrics/ClassLength