pry 0.10.3 → 0.14.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +439 -16
- data/LICENSE +1 -1
- data/README.md +362 -302
- data/bin/pry +4 -7
- data/lib/pry/basic_object.rb +10 -0
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +84 -97
- data/lib/pry/code/code_file.rb +37 -26
- data/lib/pry/code/code_range.rb +7 -5
- data/lib/pry/code/loc.rb +26 -13
- data/lib/pry/code.rb +42 -31
- data/lib/pry/code_object.rb +53 -28
- data/lib/pry/color_printer.rb +46 -35
- data/lib/pry/command.rb +197 -369
- data/lib/pry/command_set.rb +89 -114
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -82
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +85 -72
- data/lib/pry/commands/cat/file_formatter.rb +56 -46
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cat.rb +62 -54
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +48 -23
- data/lib/pry/commands/clear_screen.rb +20 -0
- data/lib/pry/commands/code_collector.rb +148 -131
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +23 -34
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
- data/lib/pry/commands/edit.rb +185 -157
- data/lib/pry/commands/exit.rb +40 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -16
- data/lib/pry/commands/find_method.rb +168 -162
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -149
- data/lib/pry/commands/import_set.rb +20 -15
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls/constants.rb +59 -31
- data/lib/pry/commands/ls/formatter.rb +42 -36
- data/lib/pry/commands/ls/globals.rb +38 -36
- data/lib/pry/commands/ls/grep.rb +17 -15
- data/lib/pry/commands/ls/instance_vars.rb +29 -28
- data/lib/pry/commands/ls/interrogatable.rb +18 -12
- data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
- data/lib/pry/commands/ls/local_names.rb +26 -24
- data/lib/pry/commands/ls/local_vars.rb +38 -30
- data/lib/pry/commands/ls/ls_entity.rb +47 -52
- data/lib/pry/commands/ls/methods.rb +49 -51
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -21
- data/lib/pry/commands/ls.rb +124 -103
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +92 -82
- data/lib/pry/commands/pry_backtrace.rb +22 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +33 -27
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +57 -42
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +56 -29
- data/lib/pry/commands/shell_mode.rb +22 -18
- data/lib/pry/commands/show_doc.rb +80 -70
- data/lib/pry/commands/show_info.rb +194 -155
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +110 -42
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +20 -16
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/watch_expression.rb +89 -84
- data/lib/pry/commands/whereami.rb +156 -141
- data/lib/pry/commands/wtf.rb +78 -40
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/config.rb +310 -20
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +22 -9
- data/lib/pry/editor.rb +56 -34
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -18
- data/lib/pry/forwardable.rb +27 -0
- data/lib/pry/helpers/base_helpers.rb +20 -62
- data/lib/pry/helpers/command_helpers.rb +52 -62
- data/lib/pry/helpers/documentation_helpers.rb +21 -12
- data/lib/pry/helpers/options_helpers.rb +15 -8
- data/lib/pry/helpers/platform.rb +55 -0
- data/lib/pry/helpers/table.rb +44 -32
- data/lib/pry/helpers/text.rb +96 -85
- data/lib/pry/helpers.rb +3 -0
- data/lib/pry/history.rb +81 -55
- data/lib/pry/hooks.rb +60 -110
- data/lib/pry/indent.rb +74 -68
- data/lib/pry/input_completer.rb +199 -158
- data/lib/pry/input_lock.rb +7 -10
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method/disowned.rb +19 -5
- data/lib/pry/method/patcher.rb +14 -8
- data/lib/pry/method/weird_method_locator.rb +79 -45
- data/lib/pry/method.rb +178 -124
- data/lib/pry/object_path.rb +37 -28
- data/lib/pry/output.rb +102 -16
- data/lib/pry/pager.rb +187 -174
- data/lib/pry/prompt.rb +213 -25
- data/lib/pry/pry_class.rb +119 -98
- data/lib/pry/pry_instance.rb +261 -224
- data/lib/pry/repl.rb +83 -29
- data/lib/pry/repl_file_loader.rb +27 -22
- data/lib/pry/ring.rb +89 -0
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +190 -0
- data/lib/pry/slop/option.rb +210 -0
- data/lib/pry/slop.rb +672 -0
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable/evalable.rb +24 -0
- data/lib/pry/testable/mockable.rb +22 -0
- data/lib/pry/testable/pry_tester.rb +88 -0
- data/lib/pry/testable/utility.rb +34 -0
- data/lib/pry/testable/variables.rb +52 -0
- data/lib/pry/testable.rb +68 -0
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +20 -0
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
- data/lib/pry/wrapped_module.rb +68 -63
- data/lib/pry.rb +133 -149
- metadata +58 -69
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -32
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gist.rb +0 -101
- data/lib/pry/commands/install_command.rb +0 -53
- data/lib/pry/commands/list_prompts.rb +0 -35
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/config/behavior.rb +0 -139
- data/lib/pry/config/convenience.rb +0 -25
- data/lib/pry/config/default.rb +0 -161
- data/lib/pry/history_array.rb +0 -121
- data/lib/pry/plugins.rb +0 -103
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/rubygem.rb +0 -82
- data/lib/pry/terminal.rb +0 -79
- data/lib/pry/test/helper.rb +0 -170
data/lib/pry/pry_instance.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
#
|
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
|
@@ -16,12 +20,15 @@
|
|
16
20
|
# This will show a list of available commands and their usage. For more
|
17
21
|
# information about Pry you can refer to the following resources:
|
18
22
|
#
|
19
|
-
# *
|
23
|
+
# * https://pry.github.io
|
20
24
|
# * https://github.com/pry/pry
|
21
25
|
# * the IRC channel, which is #pry on the Freenode network
|
22
26
|
#
|
23
27
|
|
28
|
+
# rubocop:disable Metrics/ClassLength
|
24
29
|
class Pry
|
30
|
+
extend Pry::Forwardable
|
31
|
+
|
25
32
|
attr_accessor :binding_stack
|
26
33
|
attr_accessor :custom_completions
|
27
34
|
attr_accessor :eval_string
|
@@ -32,14 +39,23 @@ class Pry
|
|
32
39
|
attr_accessor :last_dir
|
33
40
|
|
34
41
|
attr_reader :last_exception
|
35
|
-
attr_reader :command_state
|
36
42
|
attr_reader :exit_value
|
37
|
-
|
38
|
-
|
43
|
+
|
44
|
+
# @since v0.12.0
|
45
|
+
attr_reader :input_ring
|
46
|
+
|
47
|
+
# @since v0.12.0
|
48
|
+
attr_reader :output_ring
|
49
|
+
|
39
50
|
attr_reader :config
|
40
51
|
|
41
|
-
|
42
|
-
|
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
|
+
|
43
59
|
EMPTY_COMPLETIONS = [].freeze
|
44
60
|
|
45
61
|
# Create a new {Pry} instance.
|
@@ -52,7 +68,7 @@ class Pry
|
|
52
68
|
# The object to use for commands.
|
53
69
|
# @option options [Hash] :hooks
|
54
70
|
# The defined hook Procs.
|
55
|
-
# @option options [
|
71
|
+
# @option options [Pry::Prompt] :prompt
|
56
72
|
# The array of Procs to use for prompts.
|
57
73
|
# @option options [Proc] :print
|
58
74
|
# The Proc to use for printing return values.
|
@@ -62,37 +78,33 @@ class Pry
|
|
62
78
|
# The backtrace of the session's `binding.pry` line, if applicable.
|
63
79
|
# @option options [Object] :target
|
64
80
|
# The initial context for this session.
|
65
|
-
def initialize(options={})
|
81
|
+
def initialize(options = {})
|
66
82
|
@binding_stack = []
|
67
|
-
@indent = Pry::Indent.new
|
68
|
-
@
|
69
|
-
@eval_string = ""
|
83
|
+
@indent = Pry::Indent.new(self)
|
84
|
+
@eval_string = ''.dup
|
70
85
|
@backtrace = options.delete(:backtrace) || caller
|
71
86
|
target = options.delete(:target)
|
72
|
-
@config =
|
73
|
-
config.merge!(options)
|
87
|
+
@config = self.class.config.merge(options)
|
74
88
|
push_prompt(config.prompt)
|
75
|
-
@
|
76
|
-
@
|
89
|
+
@input_ring = Pry::Ring.new(config.memory_size)
|
90
|
+
@output_ring = Pry::Ring.new(config.memory_size)
|
77
91
|
@custom_completions = config.command_completions
|
78
92
|
set_last_result nil
|
79
|
-
@
|
93
|
+
@input_ring << nil
|
80
94
|
push_initial_binding(target)
|
81
95
|
exec_hook(:when_started, target, options, self)
|
96
|
+
@prompt_warn = false
|
82
97
|
end
|
83
98
|
|
84
|
-
# The current prompt.
|
85
99
|
# This is the prompt at the top of the prompt stack.
|
86
|
-
#
|
87
|
-
# @example
|
88
|
-
# self.prompt = Pry::SIMPLE_PROMPT
|
89
|
-
# self.prompt # => Pry::SIMPLE_PROMPT
|
90
|
-
#
|
91
|
-
# @return [Array<Proc>] Current prompt.
|
100
|
+
# @return [Pry::Prompt] the current prompt
|
92
101
|
def prompt
|
93
102
|
prompt_stack.last
|
94
103
|
end
|
95
104
|
|
105
|
+
# Sets the Pry prompt.
|
106
|
+
# @param [Pry::Prompt] new_prompt
|
107
|
+
# @return [void]
|
96
108
|
def prompt=(new_prompt)
|
97
109
|
if prompt_stack.empty?
|
98
110
|
push_prompt new_prompt
|
@@ -103,7 +115,7 @@ class Pry
|
|
103
115
|
|
104
116
|
# Initialize this instance by pushing its initial context into the binding
|
105
117
|
# stack. If no target is given, start at the top level.
|
106
|
-
def push_initial_binding(target=nil)
|
118
|
+
def push_initial_binding(target = nil)
|
107
119
|
push_binding(target || Pry.toplevel_binding)
|
108
120
|
end
|
109
121
|
|
@@ -124,7 +136,7 @@ class Pry
|
|
124
136
|
#
|
125
137
|
# Generate completions.
|
126
138
|
#
|
127
|
-
# @param [String]
|
139
|
+
# @param [String] str
|
128
140
|
# What the user has typed so far
|
129
141
|
#
|
130
142
|
# @return [Array<String>]
|
@@ -132,9 +144,14 @@ class Pry
|
|
132
144
|
#
|
133
145
|
def complete(str)
|
134
146
|
return EMPTY_COMPLETIONS unless config.completer
|
147
|
+
|
135
148
|
Pry.critical_section do
|
136
149
|
completer = config.completer.new(config.input, self)
|
137
|
-
completer.call
|
150
|
+
completer.call(
|
151
|
+
str,
|
152
|
+
target: current_binding,
|
153
|
+
custom_completions: custom_completions.call.push(*sticky_locals.keys)
|
154
|
+
)
|
138
155
|
end
|
139
156
|
end
|
140
157
|
|
@@ -147,20 +164,20 @@ class Pry
|
|
147
164
|
# @param [Object] value
|
148
165
|
# The value to set the local to.
|
149
166
|
#
|
150
|
-
# @param [Binding]
|
167
|
+
# @param [Binding] binding
|
151
168
|
# The binding to set the local on.
|
152
169
|
#
|
153
170
|
# @return [Object]
|
154
171
|
# The value the local was set to.
|
155
172
|
#
|
156
|
-
def inject_local(name, value,
|
157
|
-
value = Proc
|
158
|
-
if
|
159
|
-
|
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
|
160
177
|
else # < 2.1
|
161
178
|
begin
|
162
179
|
Pry.current[:pry_local] = value
|
163
|
-
|
180
|
+
binding.eval "#{name} = ::Pry.current[:pry_local]"
|
164
181
|
ensure
|
165
182
|
Pry.current[:pry_local] = nil
|
166
183
|
end
|
@@ -171,13 +188,13 @@ class Pry
|
|
171
188
|
# @return [Integer] The maximum amount of objects remembered by the inp and
|
172
189
|
# out arrays. Defaults to 100.
|
173
190
|
def memory_size
|
174
|
-
@
|
191
|
+
@output_ring.max_size
|
175
192
|
end
|
176
193
|
|
177
194
|
undef :memory_size= if method_defined? :memory_size=
|
178
195
|
def memory_size=(size)
|
179
|
-
@
|
180
|
-
@
|
196
|
+
@input_ring = Pry::Ring.new(size)
|
197
|
+
@output_ring = Pry::Ring.new(size)
|
181
198
|
end
|
182
199
|
|
183
200
|
# Inject all the sticky locals into the current binding.
|
@@ -197,21 +214,22 @@ class Pry
|
|
197
214
|
end
|
198
215
|
|
199
216
|
def sticky_locals
|
200
|
-
{
|
201
|
-
|
202
|
-
|
217
|
+
{
|
218
|
+
_in_: input_ring,
|
219
|
+
_out_: output_ring,
|
220
|
+
pry_instance: self,
|
203
221
|
_ex_: last_exception && last_exception.wrapped_exception,
|
204
222
|
_file_: last_file,
|
205
223
|
_dir_: last_dir,
|
206
224
|
_: proc { last_result },
|
207
|
-
__: proc {
|
225
|
+
__: proc { output_ring[-2] }
|
208
226
|
}.merge(config.extra_sticky_locals)
|
209
227
|
end
|
210
228
|
|
211
229
|
# Reset the current eval string. If the user has entered part of a multiline
|
212
230
|
# expression, this discards that input.
|
213
231
|
def reset_eval_string
|
214
|
-
@eval_string =
|
232
|
+
@eval_string = ''.dup
|
215
233
|
end
|
216
234
|
|
217
235
|
# Pass a line of input to Pry.
|
@@ -234,7 +252,7 @@ class Pry
|
|
234
252
|
# @return [Boolean] Is Pry ready to accept more input?
|
235
253
|
# @raise [Exception] If the user uses the `raise-up` command, this method
|
236
254
|
# will raise that exception.
|
237
|
-
def eval(line, options={})
|
255
|
+
def eval(line, options = {})
|
238
256
|
return false if @stopped
|
239
257
|
|
240
258
|
exit_value = nil
|
@@ -242,7 +260,7 @@ class Pry
|
|
242
260
|
exit_value = catch(:breakout) do
|
243
261
|
handle_line(line, options)
|
244
262
|
# We use 'return !@stopped' here instead of 'return true' so that if
|
245
|
-
# handle_line has stopped this pry instance (e.g. by opening
|
263
|
+
# handle_line has stopped this pry instance (e.g. by opening pry_instance.repl and
|
246
264
|
# then popping all the bindings) we still exit immediately.
|
247
265
|
return !@stopped
|
248
266
|
end
|
@@ -254,98 +272,15 @@ class Pry
|
|
254
272
|
|
255
273
|
# TODO: make this configurable?
|
256
274
|
raise exception if exception
|
257
|
-
return false
|
258
|
-
end
|
259
|
-
|
260
|
-
def handle_line(line, options)
|
261
|
-
if line.nil?
|
262
|
-
config.control_d_handler.call(@eval_string, self)
|
263
|
-
return
|
264
|
-
end
|
265
|
-
|
266
|
-
ensure_correct_encoding!(line)
|
267
|
-
Pry.history << line unless options[:generated]
|
268
|
-
|
269
|
-
@suppress_output = false
|
270
|
-
inject_sticky_locals!
|
271
|
-
begin
|
272
|
-
if !process_command_safely(line.lstrip)
|
273
|
-
@eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
|
274
|
-
end
|
275
|
-
rescue RescuableException => e
|
276
|
-
self.last_exception = e
|
277
|
-
result = e
|
278
275
|
|
279
|
-
|
280
|
-
show_result(result)
|
281
|
-
end
|
282
|
-
return
|
283
|
-
end
|
284
|
-
|
285
|
-
# This hook is supposed to be executed after each line of ruby code
|
286
|
-
# has been read (regardless of whether eval_string is yet a complete expression)
|
287
|
-
exec_hook :after_read, eval_string, self
|
288
|
-
|
289
|
-
begin
|
290
|
-
complete_expr = Pry::Code.complete_expression?(@eval_string)
|
291
|
-
rescue SyntaxError => e
|
292
|
-
output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}"
|
293
|
-
reset_eval_string
|
294
|
-
end
|
295
|
-
|
296
|
-
if complete_expr
|
297
|
-
if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/
|
298
|
-
@suppress_output = true
|
299
|
-
end
|
300
|
-
|
301
|
-
# A bug in jruby makes java.lang.Exception not rescued by
|
302
|
-
# `rescue Pry::RescuableException` clause.
|
303
|
-
#
|
304
|
-
# * https://github.com/pry/pry/issues/854
|
305
|
-
# * https://jira.codehaus.org/browse/JRUBY-7100
|
306
|
-
#
|
307
|
-
# Until that gets fixed upstream, treat java.lang.Exception
|
308
|
-
# as an additional exception to be rescued explicitly.
|
309
|
-
#
|
310
|
-
# This workaround has a side effect: java exceptions specified
|
311
|
-
# in `Pry.config.exception_whitelist` are ignored.
|
312
|
-
jruby_exceptions = []
|
313
|
-
if Pry::Helpers::BaseHelpers.jruby?
|
314
|
-
jruby_exceptions << Java::JavaLang::Exception
|
315
|
-
end
|
316
|
-
|
317
|
-
begin
|
318
|
-
# Reset eval string, in case we're evaluating Ruby that does something
|
319
|
-
# like open a nested REPL on this instance.
|
320
|
-
eval_string = @eval_string
|
321
|
-
reset_eval_string
|
322
|
-
|
323
|
-
result = evaluate_ruby(eval_string)
|
324
|
-
rescue RescuableException, *jruby_exceptions => e
|
325
|
-
# Eliminate following warning:
|
326
|
-
# warning: singleton on non-persistent Java type X
|
327
|
-
# (http://wiki.jruby.org/Persistence)
|
328
|
-
if Pry::Helpers::BaseHelpers.jruby? && e.class.respond_to?('__persistent__')
|
329
|
-
e.class.__persistent__ = true
|
330
|
-
end
|
331
|
-
self.last_exception = e
|
332
|
-
result = e
|
333
|
-
end
|
334
|
-
|
335
|
-
Pry.critical_section do
|
336
|
-
show_result(result)
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
throw(:breakout) if current_binding.nil?
|
276
|
+
false
|
341
277
|
end
|
342
|
-
private :handle_line
|
343
278
|
|
344
|
-
# Potentially deprecated
|
279
|
+
# Potentially deprecated. Use `Pry::REPL.new(pry, :target => target).start`
|
345
280
|
# (If nested sessions are going to exist, this method is fine, but a goal is
|
346
281
|
# to come up with an alternative to nested sessions altogether.)
|
347
282
|
def repl(target = nil)
|
348
|
-
Pry::REPL.new(self, :
|
283
|
+
Pry::REPL.new(self, target: target).start
|
349
284
|
end
|
350
285
|
|
351
286
|
def evaluate_ruby(code)
|
@@ -365,16 +300,14 @@ class Pry
|
|
365
300
|
exception_handler.call(output, result, self)
|
366
301
|
elsif should_print?
|
367
302
|
print.call(output, result, self)
|
368
|
-
else
|
369
|
-
# nothin'
|
370
303
|
end
|
371
304
|
rescue RescuableException => e
|
372
305
|
# Being uber-paranoid here, given that this exception arose because we couldn't
|
373
306
|
# serialize something in the user's program, let's not assume we can serialize
|
374
307
|
# the exception either.
|
375
308
|
begin
|
376
|
-
output.puts "(pry) output error: #{e.inspect}"
|
377
|
-
rescue RescuableException
|
309
|
+
output.puts "(pry) output error: #{e.inspect}\n#{e.backtrace.join("\n")}"
|
310
|
+
rescue RescuableException
|
378
311
|
if last_result_is_exception?
|
379
312
|
output.puts "(pry) output error: failed to show exception"
|
380
313
|
else
|
@@ -385,27 +318,20 @@ class Pry
|
|
385
318
|
output.flush if output.respond_to?(:flush)
|
386
319
|
end
|
387
320
|
|
388
|
-
# Force `eval_string` into the encoding of `val`. [Issue #284]
|
389
|
-
def ensure_correct_encoding!(val)
|
390
|
-
if @eval_string.empty? &&
|
391
|
-
val.respond_to?(:encoding) &&
|
392
|
-
val.encoding != @eval_string.encoding
|
393
|
-
@eval_string.force_encoding(val.encoding)
|
394
|
-
end
|
395
|
-
end
|
396
|
-
private :ensure_correct_encoding!
|
397
|
-
|
398
321
|
# If the given line is a valid command, process it in the context of the
|
399
322
|
# current `eval_string` and binding.
|
400
323
|
# @param [String] val The line to process.
|
401
324
|
# @return [Boolean] `true` if `val` is a command, `false` otherwise
|
402
325
|
def process_command(val)
|
326
|
+
val = val.lstrip if /^\s\S/ !~ val
|
403
327
|
val = val.chomp
|
404
|
-
result = commands.process_line(
|
405
|
-
|
406
|
-
:
|
407
|
-
:
|
408
|
-
:
|
328
|
+
result = commands.process_line(
|
329
|
+
val,
|
330
|
+
target: current_binding,
|
331
|
+
output: output,
|
332
|
+
eval_string: @eval_string,
|
333
|
+
pry_instance: self,
|
334
|
+
hooks: hooks
|
409
335
|
)
|
410
336
|
|
411
337
|
# set a temporary (just so we can inject the value we want into eval_string)
|
@@ -415,11 +341,11 @@ class Pry
|
|
415
341
|
# command was matched and invoked then `result.command?` returns true,
|
416
342
|
# otherwise it returns false.
|
417
343
|
if result.command?
|
418
|
-
|
344
|
+
unless result.void_command?
|
419
345
|
# the command that was invoked was non-void (had a return value) and so we make
|
420
346
|
# the value of the current expression equal to the return value
|
421
347
|
# of the command.
|
422
|
-
@eval_string
|
348
|
+
@eval_string = "::Pry.current[:pry_cmd_result].retval\n"
|
423
349
|
end
|
424
350
|
true
|
425
351
|
else
|
@@ -433,7 +359,9 @@ class Pry
|
|
433
359
|
# @return [Boolean] `true` if `val` is a command, `false` otherwise
|
434
360
|
def process_command_safely(val)
|
435
361
|
process_command(val)
|
436
|
-
rescue CommandError,
|
362
|
+
rescue CommandError,
|
363
|
+
Pry::Slop::InvalidOptionError,
|
364
|
+
MethodSource::SourceNotFoundError => e
|
437
365
|
Pry.last_internal_error = e
|
438
366
|
output.puts "Error: #{e.message}"
|
439
367
|
true
|
@@ -445,11 +373,12 @@ class Pry
|
|
445
373
|
# @example
|
446
374
|
# pry_instance.run_command("ls -m")
|
447
375
|
def run_command(val)
|
448
|
-
commands.process_line(
|
449
|
-
|
450
|
-
:
|
451
|
-
:
|
452
|
-
:
|
376
|
+
commands.process_line(
|
377
|
+
val,
|
378
|
+
eval_string: @eval_string,
|
379
|
+
target: current_binding,
|
380
|
+
pry_instance: self,
|
381
|
+
output: output
|
453
382
|
)
|
454
383
|
Pry::Command::VOID_VALUE
|
455
384
|
end
|
@@ -467,8 +396,8 @@ class Pry
|
|
467
396
|
hooks.exec_hook(name, *args, &block).tap do
|
468
397
|
hooks.errors[e_before..-1].each do |e|
|
469
398
|
output.puts "#{name} hook failed: #{e.class}: #{e.message}"
|
470
|
-
output.puts
|
471
|
-
output.puts "(see
|
399
|
+
output.puts e.backtrace.first.to_s
|
400
|
+
output.puts "(see pry_instance.hooks.errors to debug)"
|
472
401
|
end
|
473
402
|
end
|
474
403
|
end
|
@@ -477,23 +406,19 @@ class Pry
|
|
477
406
|
# This method should not need to be invoked directly.
|
478
407
|
# @param [Object] result The result.
|
479
408
|
# @param [String] code The code that was run.
|
480
|
-
def set_last_result(result, code="")
|
409
|
+
def set_last_result(result, code = "")
|
481
410
|
@last_result_is_exception = false
|
482
|
-
@
|
411
|
+
@output_ring << result
|
483
412
|
|
484
413
|
self.last_result = result unless code =~ /\A\s*\z/
|
485
414
|
end
|
486
415
|
|
487
|
-
#
|
488
416
|
# Set the last exception for a session.
|
489
|
-
#
|
490
|
-
|
491
|
-
# the last exception.
|
492
|
-
#
|
493
|
-
def last_exception=(e)
|
494
|
-
last_exception = Pry::LastException.new(e)
|
417
|
+
# @param [Exception] exception The last exception.
|
418
|
+
def last_exception=(exception)
|
495
419
|
@last_result_is_exception = true
|
496
|
-
|
420
|
+
last_exception = Pry::LastException.new(exception)
|
421
|
+
@output_ring << last_exception
|
497
422
|
@last_exception = last_exception
|
498
423
|
end
|
499
424
|
|
@@ -501,12 +426,12 @@ class Pry
|
|
501
426
|
# This method should not need to be invoked directly.
|
502
427
|
# @param [String] code The code we just eval'd
|
503
428
|
def update_input_history(code)
|
504
|
-
# Always push to the @
|
505
|
-
@
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
429
|
+
# Always push to the @input_ring as the @output_ring is always pushed to.
|
430
|
+
@input_ring << code
|
431
|
+
return unless code
|
432
|
+
|
433
|
+
Pry.line_buffer.push(*code.each_line)
|
434
|
+
Pry.current_line += code.lines.count
|
510
435
|
end
|
511
436
|
|
512
437
|
# @return [Boolean] True if the last result is an exception that was raised,
|
@@ -527,28 +452,42 @@ class Pry
|
|
527
452
|
# @return [String] The prompt.
|
528
453
|
def select_prompt
|
529
454
|
object = current_binding.eval('self')
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
:cont => !@eval_string.empty?})
|
455
|
+
open_token = @indent.open_delimiters.last || @indent.stack.last
|
456
|
+
|
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
|
+
)
|
546
470
|
|
547
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
|
+
|
548
488
|
# If input buffer is empty then use normal prompt
|
549
489
|
if eval_string.empty?
|
550
490
|
generate_prompt(Array(prompt).first, c)
|
551
|
-
|
552
491
|
# Otherwise use the wait prompt (indicating multi-line expression)
|
553
492
|
else
|
554
493
|
generate_prompt(Array(prompt).last, c)
|
@@ -556,44 +495,30 @@ class Pry
|
|
556
495
|
end
|
557
496
|
end
|
558
497
|
|
559
|
-
def generate_prompt(prompt_proc, conf)
|
560
|
-
if prompt_proc.arity == 1
|
561
|
-
prompt_proc.call(conf)
|
562
|
-
else
|
563
|
-
prompt_proc.call(conf.object, conf.nesting_level, conf._pry_)
|
564
|
-
end
|
565
|
-
end
|
566
|
-
private :generate_prompt
|
567
|
-
|
568
|
-
# the array that the prompt stack is stored in
|
569
|
-
def prompt_stack
|
570
|
-
@prompt_stack ||= Array.new
|
571
|
-
end
|
572
|
-
private :prompt_stack
|
573
|
-
|
574
498
|
# Pushes the current prompt onto a stack that it can be restored from later.
|
575
499
|
# Use this if you wish to temporarily change the prompt.
|
576
|
-
#
|
577
|
-
# @return [Array<Proc>] new_prompt
|
500
|
+
#
|
578
501
|
# @example
|
579
|
-
#
|
580
|
-
#
|
502
|
+
# push_prompt(Pry::Prompt[:my_prompt])
|
503
|
+
#
|
504
|
+
# @param [Pry::Prompt] new_prompt
|
505
|
+
# @return [Pry::Prompt] new_prompt
|
581
506
|
def push_prompt(new_prompt)
|
582
507
|
prompt_stack.push new_prompt
|
583
508
|
end
|
584
509
|
|
585
|
-
# Pops the current prompt off of the prompt stack.
|
586
|
-
#
|
587
|
-
#
|
588
|
-
#
|
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
|
+
#
|
589
514
|
# @example
|
590
|
-
#
|
591
|
-
#
|
592
|
-
# pry = Pry.new :prompt => prompt1
|
593
|
-
# pry.push_prompt(prompt2)
|
515
|
+
# pry = Pry.new(prompt: Pry::Prompt[:my_prompt1])
|
516
|
+
# pry.push_prompt(Pry::Prompt[:my_prompt2])
|
594
517
|
# pry.pop_prompt # => prompt2
|
595
518
|
# pry.pop_prompt # => prompt1
|
596
519
|
# pry.pop_prompt # => prompt1
|
520
|
+
#
|
521
|
+
# @return [Pry::Prompt] the prompt being popped
|
597
522
|
def pop_prompt
|
598
523
|
prompt_stack.size > 1 ? prompt_stack.pop : prompt
|
599
524
|
end
|
@@ -601,7 +526,7 @@ class Pry
|
|
601
526
|
undef :pager if method_defined? :pager
|
602
527
|
# Returns the currently configured pager
|
603
528
|
# @example
|
604
|
-
#
|
529
|
+
# pry_instance.pager.page text
|
605
530
|
def pager
|
606
531
|
Pry::Pager.new(self)
|
607
532
|
end
|
@@ -609,7 +534,7 @@ class Pry
|
|
609
534
|
undef :output if method_defined? :output
|
610
535
|
# Returns an output device
|
611
536
|
# @example
|
612
|
-
#
|
537
|
+
# pry_instance.output.puts "ohai!"
|
613
538
|
def output
|
614
539
|
Pry::Output.new(self)
|
615
540
|
end
|
@@ -635,7 +560,7 @@ class Pry
|
|
635
560
|
raise ArgumentError, "wrong number of arguments"
|
636
561
|
elsif !args.first.respond_to?(:exception)
|
637
562
|
raise TypeError, "exception class/object expected"
|
638
|
-
elsif args.
|
563
|
+
elsif args.size == 1
|
639
564
|
args.first.exception
|
640
565
|
else
|
641
566
|
args.first.exception(args[1])
|
@@ -643,7 +568,7 @@ class Pry
|
|
643
568
|
|
644
569
|
raise TypeError, "exception object expected" unless exception.is_a? Exception
|
645
570
|
|
646
|
-
exception.set_backtrace(args.
|
571
|
+
exception.set_backtrace(args.size == 3 ? args[2] : caller(1))
|
647
572
|
|
648
573
|
if force || binding_stack.one?
|
649
574
|
binding_stack.clear
|
@@ -653,12 +578,124 @@ class Pry
|
|
653
578
|
raise exception
|
654
579
|
end
|
655
580
|
end
|
656
|
-
|
657
|
-
def raise_up
|
581
|
+
|
582
|
+
def raise_up(*args)
|
583
|
+
raise_up_common(false, *args)
|
584
|
+
end
|
585
|
+
|
586
|
+
def raise_up!(*args)
|
587
|
+
raise_up_common(true, *args)
|
588
|
+
end
|
658
589
|
|
659
590
|
# Convenience accessor for the `quiet` config key.
|
660
591
|
# @return [Boolean]
|
661
592
|
def quiet?
|
662
593
|
config.quiet
|
663
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
|
664
700
|
end
|
701
|
+
# rubocop:enable Metrics/ClassLength
|