pry 0.10.3 → 0.14.2
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.
- 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/method.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'method_source'
|
2
4
|
|
3
5
|
class Pry
|
4
6
|
class << self
|
@@ -15,51 +17,52 @@ class Pry
|
|
15
17
|
|
16
18
|
# This class wraps the normal `Method` and `UnboundMethod` classes
|
17
19
|
# to provide extra functionality useful to Pry.
|
18
|
-
class Method
|
19
|
-
require 'pry/method/weird_method_locator'
|
20
|
-
require 'pry/method/disowned'
|
21
|
-
require 'pry/method/patcher'
|
22
|
-
|
20
|
+
class Method # rubocop:disable Metrics/ClassLength
|
23
21
|
extend Helpers::BaseHelpers
|
22
|
+
extend Forwardable
|
23
|
+
|
24
24
|
include Helpers::BaseHelpers
|
25
25
|
include Helpers::DocumentationHelpers
|
26
26
|
include CodeObject::Helpers
|
27
27
|
|
28
28
|
class << self
|
29
29
|
# Given a string representing a method name and optionally a binding to
|
30
|
-
# search in, find and return the requested method wrapped in a
|
31
|
-
# instance.
|
30
|
+
# search in, find and return the requested method wrapped in a
|
31
|
+
# `Pry::Method` instance.
|
32
32
|
#
|
33
33
|
# @param [String] name The name of the method to retrieve.
|
34
34
|
# @param [Binding] target The context in which to search for the method.
|
35
35
|
# @param [Hash] options
|
36
|
-
# @option options [Boolean] :instance Look for an instance method if
|
37
|
-
# contain any context.
|
38
|
-
# @option options [Boolean] :methods Look for a bound/singleton method if
|
39
|
-
#
|
40
|
-
# @return [Pry::Method, nil] A `Pry::Method` instance containing the
|
41
|
-
# method, or `nil` if name is `nil` or no method could be
|
42
|
-
|
36
|
+
# @option options [Boolean] :instance Look for an instance method if
|
37
|
+
# `name` doesn't contain any context.
|
38
|
+
# @option options [Boolean] :methods Look for a bound/singleton method if
|
39
|
+
# `name` doesn't contain any context.
|
40
|
+
# @return [Pry::Method, nil] A `Pry::Method` instance containing the
|
41
|
+
# requested method, or `nil` if name is `nil` or no method could be
|
42
|
+
# located matching the parameters.
|
43
|
+
def from_str(name, target = TOPLEVEL_BINDING, options = {})
|
43
44
|
if name.nil?
|
44
45
|
nil
|
45
46
|
elsif name.to_s =~ /(.+)\#(\S+)\Z/
|
46
|
-
context
|
47
|
+
context = Regexp.last_match(1)
|
48
|
+
meth_name = Regexp.last_match(2)
|
47
49
|
from_module(target.eval(context), meth_name, target)
|
48
50
|
elsif name.to_s =~ /(.+)(\[\])\Z/
|
49
|
-
context
|
51
|
+
context = Regexp.last_match(1)
|
52
|
+
meth_name = Regexp.last_match(2)
|
50
53
|
from_obj(target.eval(context), meth_name, target)
|
51
54
|
elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/
|
52
|
-
context
|
55
|
+
context = Regexp.last_match(1)
|
56
|
+
meth_name = Regexp.last_match(3)
|
53
57
|
from_obj(target.eval(context), meth_name, target)
|
54
58
|
elsif options[:instance]
|
55
59
|
from_module(target.eval("self"), name, target)
|
56
60
|
elsif options[:methods]
|
57
61
|
from_obj(target.eval("self"), name, target)
|
58
62
|
else
|
59
|
-
from_str(name, target, :
|
60
|
-
from_str(name, target, :
|
63
|
+
from_str(name, target, instance: true) ||
|
64
|
+
from_str(name, target, methods: true)
|
61
65
|
end
|
62
|
-
|
63
66
|
rescue Pry::RescuableException
|
64
67
|
nil
|
65
68
|
end
|
@@ -68,26 +71,33 @@ class Pry
|
|
68
71
|
# use it to instantiate a `Pry::Method`. Return `nil` if this isn't
|
69
72
|
# possible.
|
70
73
|
#
|
71
|
-
# @param [Binding]
|
74
|
+
# @param [Binding] binding
|
72
75
|
# @return [Pry::Method, nil]
|
73
76
|
#
|
74
|
-
def from_binding(
|
75
|
-
meth_name =
|
77
|
+
def from_binding(binding)
|
78
|
+
meth_name = binding.eval('::Kernel.__method__')
|
76
79
|
if [:__script__, nil].include?(meth_name)
|
77
80
|
nil
|
78
81
|
else
|
79
|
-
method =
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
method =
|
83
|
+
begin
|
84
|
+
if Object === binding.eval('self') # rubocop:disable Style/CaseEquality
|
85
|
+
new(
|
86
|
+
Kernel.instance_method(:method)
|
87
|
+
.bind(binding.eval("self"))
|
88
|
+
.call(meth_name)
|
89
|
+
)
|
90
|
+
else
|
91
|
+
str = 'class << self; self; end' \
|
92
|
+
'.instance_method(::Kernel.__method__).bind(self)'
|
93
|
+
new(binding.eval(str))
|
94
|
+
end
|
95
|
+
rescue NameError, NoMethodError # rubocop:disable Lint/ShadowedException
|
96
|
+
Disowned.new(binding.eval('self'), meth_name.to_s)
|
97
|
+
end
|
98
|
+
|
99
|
+
if WeirdMethodLocator.weird_method?(method, binding)
|
100
|
+
WeirdMethodLocator.new(method, binding).find_method || method
|
91
101
|
else
|
92
102
|
method
|
93
103
|
end
|
@@ -101,11 +111,16 @@ class Pry
|
|
101
111
|
# @param [Symbol] method_type The type of method: :method or :instance_method
|
102
112
|
# @param [Binding] target The binding where the method is looked up.
|
103
113
|
# @return [Method, UnboundMethod] The 'refined' method object.
|
104
|
-
def lookup_method_via_binding(
|
114
|
+
def lookup_method_via_binding(
|
115
|
+
obj, method_name, method_type, target = TOPLEVEL_BINDING
|
116
|
+
)
|
105
117
|
Pry.current[:obj] = obj
|
106
118
|
Pry.current[:name] = method_name
|
107
119
|
receiver = obj.is_a?(Module) ? "Module" : "Kernel"
|
108
|
-
target.eval(
|
120
|
+
target.eval(
|
121
|
+
"::#{receiver}.instance_method(:#{method_type})" \
|
122
|
+
".bind(Pry.current[:obj]).call(Pry.current[:name])"
|
123
|
+
)
|
109
124
|
ensure
|
110
125
|
Pry.current[:obj] = Pry.current[:name] = nil
|
111
126
|
end
|
@@ -118,8 +133,10 @@ class Pry
|
|
118
133
|
# @param [String] name
|
119
134
|
# @param [Binding] target The binding where the method is looked up.
|
120
135
|
# @return [Pry::Method, nil]
|
121
|
-
def from_class(klass, name, target=TOPLEVEL_BINDING)
|
122
|
-
new(lookup_method_via_binding(klass, name, :instance_method, target))
|
136
|
+
def from_class(klass, name, target = TOPLEVEL_BINDING)
|
137
|
+
new(lookup_method_via_binding(klass, name, :instance_method, target))
|
138
|
+
rescue StandardError
|
139
|
+
nil
|
123
140
|
end
|
124
141
|
alias from_module from_class
|
125
142
|
|
@@ -131,20 +148,27 @@ class Pry
|
|
131
148
|
# @param [String] name
|
132
149
|
# @param [Binding] target The binding where the method is looked up.
|
133
150
|
# @return [Pry::Method, nil]
|
134
|
-
def from_obj(obj, name, target=TOPLEVEL_BINDING)
|
135
|
-
new(lookup_method_via_binding(obj, name, :method, target))
|
151
|
+
def from_obj(obj, name, target = TOPLEVEL_BINDING)
|
152
|
+
new(lookup_method_via_binding(obj, name, :method, target))
|
153
|
+
rescue StandardError
|
154
|
+
nil
|
136
155
|
end
|
137
156
|
|
138
157
|
# Get all of the instance methods of a `Class` or `Module`
|
139
158
|
# @param [Class,Module] klass
|
140
159
|
# @param [Boolean] include_super Whether to include methods from ancestors.
|
141
160
|
# @return [Array[Pry::Method]]
|
142
|
-
def all_from_class(klass, include_super=true)
|
143
|
-
%w
|
144
|
-
safe_send(
|
145
|
-
|
161
|
+
def all_from_class(klass, include_super = true)
|
162
|
+
%w[public protected private].flat_map do |visibility|
|
163
|
+
safe_send(
|
164
|
+
klass, :"#{visibility}_instance_methods", include_super
|
165
|
+
).map do |method_name|
|
166
|
+
new(
|
167
|
+
safe_send(klass, :instance_method, method_name),
|
168
|
+
visibility: visibility.to_sym
|
169
|
+
)
|
146
170
|
end
|
147
|
-
end
|
171
|
+
end
|
148
172
|
end
|
149
173
|
|
150
174
|
#
|
@@ -157,28 +181,23 @@ class Pry
|
|
157
181
|
#
|
158
182
|
# @return [Array[Pry::Method]]
|
159
183
|
#
|
160
|
-
def all_from_obj(obj, include_super=true)
|
184
|
+
def all_from_obj(obj, include_super = true)
|
161
185
|
all_from_class(singleton_class_of(obj), include_super)
|
162
186
|
end
|
163
187
|
|
164
|
-
#
|
165
|
-
# @deprecated
|
166
|
-
# please use {#all_from_obj} instead.
|
167
|
-
# the `method_type` argument is ignored.
|
168
|
-
#
|
169
|
-
def all_from_common(obj, method_type = nil, include_super=true)
|
170
|
-
all_from_obj(obj, include_super)
|
171
|
-
end
|
172
|
-
|
173
188
|
# Get every `Class` and `Module`, in order, that will be checked when looking
|
174
189
|
# for an instance method to call on this object.
|
175
190
|
# @param [Object] obj
|
176
191
|
# @return [Array[Class, Module]]
|
177
192
|
def resolution_order(obj)
|
178
|
-
if Class === obj
|
193
|
+
if Class === obj # rubocop:disable Style/CaseEquality
|
179
194
|
singleton_class_resolution_order(obj) + instance_resolution_order(Class)
|
180
195
|
else
|
181
|
-
klass =
|
196
|
+
klass = begin
|
197
|
+
singleton_class_of(obj)
|
198
|
+
rescue StandardError
|
199
|
+
obj.class
|
200
|
+
end
|
182
201
|
instance_resolution_order(klass)
|
183
202
|
end
|
184
203
|
end
|
@@ -199,11 +218,17 @@ class Pry
|
|
199
218
|
end
|
200
219
|
|
201
220
|
def singleton_method_definition?(name, definition_line)
|
202
|
-
|
221
|
+
regexp =
|
222
|
+
/^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|
|
223
|
+
^def\s*self\.#{Regexp.escape(name)}/x
|
224
|
+
regexp =~ definition_line.strip
|
203
225
|
end
|
204
226
|
|
205
227
|
def instance_method_definition?(name, definition_line)
|
206
|
-
|
228
|
+
regexp =
|
229
|
+
/^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|
|
230
|
+
^def\s*#{Regexp.escape(name)}/x
|
231
|
+
regexp =~ definition_line.strip
|
207
232
|
end
|
208
233
|
|
209
234
|
# Get the singleton classes of superclasses that could define methods on
|
@@ -212,33 +237,37 @@ class Pry
|
|
212
237
|
# the lowest copy will be returned.
|
213
238
|
def singleton_class_resolution_order(klass)
|
214
239
|
ancestors = Pry::Method.safe_send(klass, :ancestors)
|
215
|
-
resolution_order = ancestors.grep(Class).
|
240
|
+
resolution_order = ancestors.grep(Class).flat_map do |anc|
|
216
241
|
[singleton_class_of(anc), *singleton_class_of(anc).included_modules]
|
217
|
-
end
|
242
|
+
end
|
218
243
|
|
219
244
|
resolution_order.reverse.uniq.reverse - Class.included_modules
|
220
245
|
end
|
221
246
|
|
222
247
|
def singleton_class_of(obj)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
obj.class
|
227
|
-
end
|
248
|
+
class << obj; self; end
|
249
|
+
rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ...
|
250
|
+
obj.class
|
228
251
|
end
|
229
252
|
end
|
230
253
|
|
231
|
-
#
|
254
|
+
# Workaround for https://github.com/pry/pry/pull/2086
|
255
|
+
def_delegators :@method, :owner, :parameters, :receiver
|
256
|
+
|
257
|
+
# A new instance of `Pry::Method` wrapping the given `::Method`,
|
258
|
+
# `UnboundMethod`, or `Proc`.
|
232
259
|
#
|
233
260
|
# @param [::Method, UnboundMethod, Proc] method
|
234
261
|
# @param [Hash] known_info Can be used to pre-cache expensive to compute stuff.
|
235
262
|
# @return [Pry::Method]
|
236
|
-
def initialize(method, known_info={})
|
263
|
+
def initialize(method, known_info = {})
|
237
264
|
@method = method
|
238
265
|
@visibility = known_info[:visibility]
|
239
266
|
end
|
240
267
|
|
241
|
-
# Get the name of the method as a String, regardless of the underlying
|
268
|
+
# Get the name of the method as a String, regardless of the underlying
|
269
|
+
# Method#name type.
|
270
|
+
#
|
242
271
|
# @return [String]
|
243
272
|
def name
|
244
273
|
@method.name.to_s
|
@@ -298,7 +327,8 @@ class Pry
|
|
298
327
|
# @return [String, nil] The documentation for the method, or `nil` if it's
|
299
328
|
# unavailable.
|
300
329
|
def doc
|
301
|
-
@doc ||=
|
330
|
+
@doc ||=
|
331
|
+
case source_type
|
302
332
|
when :c
|
303
333
|
info = pry_doc_info
|
304
334
|
info.docstring if info
|
@@ -317,7 +347,7 @@ class Pry
|
|
317
347
|
# `nil` if the filename is unavailable.
|
318
348
|
def source_file
|
319
349
|
if source_location.nil?
|
320
|
-
if
|
350
|
+
if source_type == :c
|
321
351
|
info = pry_doc_info
|
322
352
|
info.file if info
|
323
353
|
end
|
@@ -341,33 +371,38 @@ class Pry
|
|
341
371
|
# @return [Symbol] The visibility of the method. May be `:public`,
|
342
372
|
# `:protected`, or `:private`.
|
343
373
|
def visibility
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
374
|
+
@visibility ||=
|
375
|
+
if owner.public_instance_methods.any? { |m| m.to_s == name }
|
376
|
+
:public
|
377
|
+
elsif owner.protected_instance_methods.any? { |m| m.to_s == name }
|
378
|
+
:protected
|
379
|
+
elsif owner.private_instance_methods.any? { |m| m.to_s == name }
|
380
|
+
:private
|
381
|
+
else
|
382
|
+
:none
|
383
|
+
end
|
353
384
|
end
|
354
385
|
|
355
386
|
# @return [String] A representation of the method's signature, including its
|
356
387
|
# name and parameters. Optional and "rest" parameters are marked with `*`
|
357
|
-
# and block parameters with `&`.
|
358
|
-
# they're given numbered names instead.
|
388
|
+
# and block parameters with `&`. Keyword arguments are shown with `:`
|
389
|
+
# If the parameter names are unavailable, they're given numbered names instead.
|
359
390
|
# Paraphrased from `awesome_print` gem.
|
360
391
|
def signature
|
361
392
|
if respond_to?(:parameters)
|
362
|
-
args = parameters.inject([]) do |
|
363
|
-
name ||= (
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
393
|
+
args = parameters.inject([]) do |args_array, (arg_type, name)|
|
394
|
+
name ||= (arg_type == :block ? 'block' : "arg#{args_array.size + 1}")
|
395
|
+
args_array.push(
|
396
|
+
case arg_type
|
397
|
+
when :req then name.to_s
|
398
|
+
when :opt then "#{name}=?"
|
399
|
+
when :rest then "*#{name}"
|
400
|
+
when :block then "&#{name}"
|
401
|
+
when :key then "#{name}:?"
|
402
|
+
when :keyreq then "#{name}:"
|
403
|
+
else '?'
|
404
|
+
end
|
405
|
+
)
|
371
406
|
end
|
372
407
|
else
|
373
408
|
args = (1..arity.abs).map { |i| "arg#{i}" }
|
@@ -379,8 +414,8 @@ class Pry
|
|
379
414
|
|
380
415
|
# @return [Pry::Method, nil] The wrapped method that is called when you
|
381
416
|
# use "super" in the body of this method.
|
382
|
-
def super(times=1)
|
383
|
-
if
|
417
|
+
def super(times = 1)
|
418
|
+
if @method.is_a?(UnboundMethod)
|
384
419
|
sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times)
|
385
420
|
else
|
386
421
|
sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times)
|
@@ -393,12 +428,13 @@ class Pry
|
|
393
428
|
# before any aliasing, or `nil` if it can't be determined.
|
394
429
|
def original_name
|
395
430
|
return nil if source_type != :ruby
|
431
|
+
|
396
432
|
method_name_from_first_line(source.lines.first)
|
397
433
|
end
|
398
434
|
|
399
435
|
# @return [Boolean] Was the method defined outside a source file?
|
400
436
|
def dynamically_defined?
|
401
|
-
!!(source_file
|
437
|
+
!!(source_file && source_file =~ /(\(.*\))|<.*>/)
|
402
438
|
end
|
403
439
|
|
404
440
|
# @return [Boolean] Whether the method is unbound.
|
@@ -444,30 +480,36 @@ class Pry
|
|
444
480
|
end
|
445
481
|
|
446
482
|
# @return [Boolean]
|
447
|
-
def ==(
|
448
|
-
if
|
449
|
-
|
450
|
-
|
451
|
-
@method == obj
|
452
|
-
end
|
483
|
+
def ==(other)
|
484
|
+
return other == @method if other.is_a?(Pry::Method)
|
485
|
+
|
486
|
+
@method == other
|
453
487
|
end
|
454
488
|
|
455
489
|
# @param [Class] klass
|
456
490
|
# @return [Boolean]
|
457
491
|
def is_a?(klass)
|
458
|
-
klass == Pry::Method
|
492
|
+
(klass == Pry::Method) || @method.is_a?(klass)
|
459
493
|
end
|
460
494
|
alias kind_of? is_a?
|
461
495
|
|
462
496
|
# @param [String, Symbol] method_name
|
463
497
|
# @return [Boolean]
|
464
|
-
def respond_to?(method_name)
|
465
|
-
super
|
498
|
+
def respond_to?(method_name, include_all = false)
|
499
|
+
super || @method.respond_to?(method_name, include_all)
|
466
500
|
end
|
467
501
|
|
468
502
|
# Delegate any unknown calls to the wrapped method.
|
469
503
|
def method_missing(method_name, *args, &block)
|
470
|
-
@method.
|
504
|
+
if @method.respond_to?(method_name)
|
505
|
+
@method.__send__(method_name, *args, &block)
|
506
|
+
else
|
507
|
+
super
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
def respond_to_missing?(method_name, include_private = false)
|
512
|
+
@method.respond_to?(method_name) || super
|
471
513
|
end
|
472
514
|
|
473
515
|
def comment
|
@@ -479,12 +521,18 @@ class Pry
|
|
479
521
|
# @return [YARD::CodeObjects::MethodObject]
|
480
522
|
# @raise [CommandError] when the method can't be found or `pry-doc` isn't installed.
|
481
523
|
def pry_doc_info
|
482
|
-
if
|
483
|
-
Pry::MethodInfo.info_for(@method)
|
524
|
+
if defined?(PryDoc)
|
525
|
+
Pry::MethodInfo.info_for(@method) ||
|
526
|
+
raise(
|
527
|
+
CommandError,
|
528
|
+
"Cannot locate this method: #{name}. (source_location returns nil)"
|
529
|
+
)
|
484
530
|
else
|
485
531
|
fail_msg = "Cannot locate this method: #{name}."
|
486
|
-
if mri?
|
487
|
-
fail_msg +=
|
532
|
+
if Helpers::Platform.mri?
|
533
|
+
fail_msg += " Run `gem install pry-doc` to install" \
|
534
|
+
" Ruby Core documentation," \
|
535
|
+
" and `require 'pry-doc'` to load it.\n"
|
488
536
|
end
|
489
537
|
raise CommandError, fail_msg
|
490
538
|
end
|
@@ -492,17 +540,23 @@ class Pry
|
|
492
540
|
|
493
541
|
# @param [Class, Module] ancestors The ancestors to investigate
|
494
542
|
# @return [Method] The unwrapped super-method
|
495
|
-
def super_using_ancestors(ancestors, times=1)
|
496
|
-
next_owner =
|
543
|
+
def super_using_ancestors(ancestors, times = 1)
|
544
|
+
next_owner = owner
|
497
545
|
times.times do
|
498
546
|
i = ancestors.index(next_owner) + 1
|
499
|
-
while ancestors[i] &&
|
547
|
+
while ancestors[i] &&
|
548
|
+
!(ancestors[i].method_defined?(name) ||
|
549
|
+
ancestors[i].private_method_defined?(name))
|
500
550
|
i += 1
|
501
551
|
end
|
502
|
-
next_owner = ancestors[i]
|
552
|
+
(next_owner = ancestors[i]) || (return nil)
|
503
553
|
end
|
504
554
|
|
505
|
-
|
555
|
+
begin
|
556
|
+
safe_send(next_owner, :instance_method, name)
|
557
|
+
rescue StandardError
|
558
|
+
nil
|
559
|
+
end
|
506
560
|
end
|
507
561
|
|
508
562
|
# @param [String] first_ln The first line of a method definition.
|
@@ -510,7 +564,7 @@ class Pry
|
|
510
564
|
def method_name_from_first_line(first_ln)
|
511
565
|
return nil if first_ln.strip !~ /^def /
|
512
566
|
|
513
|
-
tokens =
|
567
|
+
tokens = SyntaxHighlighter.tokenize(first_ln)
|
514
568
|
tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
|
515
569
|
tokens.each_cons(2) do |t1, t2|
|
516
570
|
if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
|
@@ -523,22 +577,22 @@ class Pry
|
|
523
577
|
|
524
578
|
def c_source
|
525
579
|
info = pry_doc_info
|
526
|
-
if info
|
527
|
-
strip_comments_from_c_code(info.source)
|
528
|
-
end
|
580
|
+
strip_comments_from_c_code(info.source) if info && info.source
|
529
581
|
end
|
530
582
|
|
531
583
|
def ruby_source
|
532
|
-
#
|
533
|
-
# hacked version of source_location for
|
534
|
-
#
|
584
|
+
# Clone of `MethodSource.source_helper` that knows to use our
|
585
|
+
# hacked version of `source_location` for our input buffer for methods
|
586
|
+
# defined in `(pry)`.
|
535
587
|
file, line = *source_location
|
536
|
-
|
588
|
+
unless file
|
589
|
+
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!"
|
590
|
+
end
|
537
591
|
|
538
592
|
begin
|
539
593
|
code = Pry::Code.from_file(file).expression_at(line)
|
540
594
|
rescue SyntaxError => e
|
541
|
-
raise MethodSource::SourceNotFoundError
|
595
|
+
raise MethodSource::SourceNotFoundError, e.message
|
542
596
|
end
|
543
597
|
strip_leading_whitespace(code)
|
544
598
|
end
|
data/lib/pry/object_path.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'strscan'
|
4
|
+
|
1
5
|
class Pry
|
2
6
|
# `ObjectPath` implements the resolution of "object paths", which are strings
|
3
7
|
# that are similar to filesystem paths but meant for traversing Ruby objects.
|
@@ -11,7 +15,7 @@ class Pry
|
|
11
15
|
# Object paths are mostly relevant in the context of the `cd` command.
|
12
16
|
# @see https://github.com/pry/pry/wiki/State-navigation
|
13
17
|
class ObjectPath
|
14
|
-
SPECIAL_TERMS = ["", "::", ".", ".."]
|
18
|
+
SPECIAL_TERMS = ["", "::", ".", ".."].freeze
|
15
19
|
|
16
20
|
# @param [String] path_string The object path expressed as a string.
|
17
21
|
# @param [Array<Binding>] current_stack The current state of the binding
|
@@ -27,36 +31,40 @@ class Pry
|
|
27
31
|
scanner = StringScanner.new(@path_string.strip)
|
28
32
|
stack = @current_stack.dup
|
29
33
|
|
30
|
-
|
31
|
-
|
34
|
+
loop do
|
35
|
+
begin
|
36
|
+
next_segment = ""
|
37
|
+
|
38
|
+
loop do
|
39
|
+
# Scan for as long as we don't see a slash
|
40
|
+
next_segment += scanner.scan(%r{[^/]*})
|
32
41
|
|
33
|
-
|
34
|
-
|
35
|
-
|
42
|
+
if complete?(next_segment) || scanner.eos?
|
43
|
+
scanner.getch # consume the slash
|
44
|
+
break
|
45
|
+
else
|
46
|
+
next_segment += scanner.getch # append the slash
|
47
|
+
end
|
48
|
+
end
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
case next_segment.chomp
|
51
|
+
when ""
|
52
|
+
stack = [stack.first]
|
53
|
+
when "::"
|
54
|
+
stack.push(TOPLEVEL_BINDING)
|
55
|
+
when "."
|
56
|
+
next
|
57
|
+
when ".."
|
58
|
+
stack.pop unless stack.size == 1
|
40
59
|
else
|
41
|
-
next_segment
|
60
|
+
stack.push(Pry.binding_for(stack.last.eval(next_segment)))
|
42
61
|
end
|
62
|
+
rescue RescuableException => e
|
63
|
+
return handle_failure(next_segment, e)
|
43
64
|
end
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
stack = [stack.first]
|
48
|
-
when "::"
|
49
|
-
stack.push(TOPLEVEL_BINDING)
|
50
|
-
when "."
|
51
|
-
next
|
52
|
-
when ".."
|
53
|
-
stack.pop unless stack.size == 1
|
54
|
-
else
|
55
|
-
stack.push(Pry.binding_for(stack.last.eval(next_segment)))
|
56
|
-
end
|
57
|
-
rescue RescuableException => e
|
58
|
-
return handle_failure(next_segment, e)
|
59
|
-
end until scanner.eos?
|
66
|
+
break if scanner.eos?
|
67
|
+
end
|
60
68
|
|
61
69
|
stack
|
62
70
|
end
|
@@ -74,9 +82,10 @@ class Pry
|
|
74
82
|
"Exception: #{err.inspect}"
|
75
83
|
].join("\n")
|
76
84
|
|
77
|
-
|
78
|
-
|
79
|
-
|
85
|
+
command_error = CommandError.new(msg)
|
86
|
+
command_error.set_backtrace(err.backtrace)
|
87
|
+
|
88
|
+
raise command_error
|
80
89
|
end
|
81
90
|
end
|
82
91
|
end
|