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/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
|