pry 0.9.12.2 → 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 +1141 -0
- data/LICENSE +2 -2
- data/README.md +466 -0
- 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 +97 -92
- data/lib/pry/code/code_file.rb +114 -0
- data/lib/pry/code/code_range.rb +7 -4
- data/lib/pry/code/loc.rb +27 -14
- data/lib/pry/code.rb +62 -90
- data/lib/pry/code_object.rb +83 -39
- data/lib/pry/color_printer.rb +66 -0
- data/lib/pry/command.rb +202 -371
- data/lib/pry/command_set.rb +151 -133
- 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 -73
- data/lib/pry/commands/cat/file_formatter.rb +56 -63
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cat.rb +64 -47
- data/lib/pry/commands/cd.rb +42 -26
- data/lib/pry/commands/change_inspector.rb +34 -0
- data/lib/pry/commands/change_prompt.rb +51 -0
- 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 +33 -24
- data/lib/pry/commands/edit.rb +183 -167
- 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 -17
- data/lib/pry/commands/find_method.rb +167 -167
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +153 -132
- 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 +42 -0
- data/lib/pry/commands/ls/constants.rb +75 -0
- data/lib/pry/commands/ls/formatter.rb +55 -0
- data/lib/pry/commands/ls/globals.rb +50 -0
- data/lib/pry/commands/ls/grep.rb +23 -0
- data/lib/pry/commands/ls/instance_vars.rb +40 -0
- data/lib/pry/commands/ls/interrogatable.rb +24 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +55 -0
- data/lib/pry/commands/ls/local_names.rb +37 -0
- data/lib/pry/commands/ls/local_vars.rb +47 -0
- data/lib/pry/commands/ls/ls_entity.rb +65 -0
- data/lib/pry/commands/ls/methods.rb +55 -0
- data/lib/pry/commands/ls/methods_helper.rb +50 -0
- data/lib/pry/commands/ls/self_methods.rb +34 -0
- data/lib/pry/commands/ls.rb +100 -303
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +93 -49
- data/lib/pry/commands/pry_backtrace.rb +22 -18
- 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 +57 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +57 -38
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +66 -34
- data/lib/pry/commands/shell_mode.rb +22 -20
- data/lib/pry/commands/show_doc.rb +80 -65
- data/lib/pry/commands/show_info.rb +193 -159
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +113 -33
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +21 -13
- data/lib/pry/commands/watch_expression/expression.rb +43 -0
- data/lib/pry/commands/watch_expression.rb +110 -0
- data/lib/pry/commands/whereami.rb +157 -134
- 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 +290 -220
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +50 -27
- data/lib/pry/editor.rb +130 -102
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +73 -0
- data/lib/pry/forwardable.rb +27 -0
- data/lib/pry/helpers/base_helpers.rb +22 -151
- data/lib/pry/helpers/command_helpers.rb +55 -63
- data/lib/pry/helpers/documentation_helpers.rb +21 -13
- 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 -86
- data/lib/pry/helpers.rb +3 -0
- data/lib/pry/history.rb +101 -70
- data/lib/pry/hooks.rb +67 -137
- data/lib/pry/indent.rb +79 -73
- data/lib/pry/input_completer.rb +283 -0
- data/lib/pry/input_lock.rb +129 -0
- data/lib/pry/inspector.rb +39 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method/disowned.rb +19 -5
- data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +51 -42
- data/lib/pry/method/weird_method_locator.rb +80 -44
- data/lib/pry/method.rb +225 -176
- data/lib/pry/object_path.rb +91 -0
- data/lib/pry/output.rb +136 -0
- data/lib/pry/pager.rb +227 -68
- data/lib/pry/prompt.rb +214 -0
- data/lib/pry/pry_class.rb +216 -289
- data/lib/pry/pry_instance.rb +438 -500
- data/lib/pry/repl.rb +256 -0
- data/lib/pry/repl_file_loader.rb +34 -35
- 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} +36 -43
- data/lib/pry/wrapped_module.rb +102 -103
- data/lib/pry.rb +135 -261
- metadata +94 -283
- data/.document +0 -2
- data/.gitignore +0 -16
- data/.travis.yml +0 -21
- data/.yardopts +0 -1
- data/CHANGELOG +0 -534
- data/CONTRIBUTORS +0 -55
- data/Gemfile +0 -9
- data/Guardfile +0 -62
- data/README.markdown +0 -400
- data/Rakefile +0 -140
- data/TODO +0 -117
- 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 -29
- 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 -102
- data/lib/pry/commands/install_command.rb +0 -51
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/completion.rb +0 -304
- data/lib/pry/custom_completions.rb +0 -6
- data/lib/pry/history_array.rb +0 -116
- data/lib/pry/plugins.rb +0 -103
- data/lib/pry/rbx_method.rb +0 -13
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/rubygem.rb +0 -74
- data/lib/pry/terminal.rb +0 -78
- data/lib/pry/test/helper.rb +0 -185
- data/man/pry.1 +0 -195
- data/man/pry.1.html +0 -204
- data/man/pry.1.ronn +0 -141
- data/pry.gemspec +0 -30
- data/spec/Procfile +0 -3
- data/spec/cli_spec.rb +0 -78
- data/spec/code_object_spec.rb +0 -277
- data/spec/code_spec.rb +0 -219
- data/spec/command_helpers_spec.rb +0 -29
- data/spec/command_integration_spec.rb +0 -644
- data/spec/command_set_spec.rb +0 -627
- data/spec/command_spec.rb +0 -821
- data/spec/commands/amend_line_spec.rb +0 -247
- data/spec/commands/bang_spec.rb +0 -19
- data/spec/commands/cat_spec.rb +0 -164
- data/spec/commands/cd_spec.rb +0 -250
- data/spec/commands/disable_pry_spec.rb +0 -25
- data/spec/commands/edit_spec.rb +0 -727
- data/spec/commands/exit_all_spec.rb +0 -34
- data/spec/commands/exit_program_spec.rb +0 -19
- data/spec/commands/exit_spec.rb +0 -34
- data/spec/commands/find_method_spec.rb +0 -70
- data/spec/commands/gem_list_spec.rb +0 -26
- data/spec/commands/gist_spec.rb +0 -79
- data/spec/commands/help_spec.rb +0 -56
- data/spec/commands/hist_spec.rb +0 -181
- data/spec/commands/jump_to_spec.rb +0 -15
- data/spec/commands/ls_spec.rb +0 -181
- data/spec/commands/play_spec.rb +0 -140
- data/spec/commands/raise_up_spec.rb +0 -56
- data/spec/commands/save_file_spec.rb +0 -177
- data/spec/commands/show_doc_spec.rb +0 -510
- data/spec/commands/show_input_spec.rb +0 -17
- data/spec/commands/show_source_spec.rb +0 -782
- data/spec/commands/whereami_spec.rb +0 -203
- data/spec/completion_spec.rb +0 -239
- data/spec/control_d_handler_spec.rb +0 -58
- data/spec/documentation_helper_spec.rb +0 -73
- data/spec/editor_spec.rb +0 -79
- data/spec/exception_whitelist_spec.rb +0 -21
- data/spec/fixtures/candidate_helper1.rb +0 -11
- data/spec/fixtures/candidate_helper2.rb +0 -8
- data/spec/fixtures/example.erb +0 -5
- data/spec/fixtures/example_nesting.rb +0 -33
- data/spec/fixtures/show_source_doc_examples.rb +0 -15
- data/spec/fixtures/testrc +0 -2
- data/spec/fixtures/testrcbad +0 -2
- data/spec/fixtures/whereami_helper.rb +0 -6
- data/spec/helper.rb +0 -34
- data/spec/helpers/bacon.rb +0 -86
- data/spec/helpers/mock_pry.rb +0 -43
- data/spec/helpers/table_spec.rb +0 -105
- data/spec/history_array_spec.rb +0 -67
- data/spec/hooks_spec.rb +0 -522
- data/spec/indent_spec.rb +0 -301
- data/spec/input_stack_spec.rb +0 -90
- data/spec/method_spec.rb +0 -482
- data/spec/prompt_spec.rb +0 -60
- data/spec/pry_defaults_spec.rb +0 -419
- data/spec/pry_history_spec.rb +0 -99
- data/spec/pry_output_spec.rb +0 -95
- data/spec/pry_spec.rb +0 -504
- data/spec/run_command_spec.rb +0 -25
- data/spec/sticky_locals_spec.rb +0 -157
- data/spec/syntax_checking_spec.rb +0 -81
- data/spec/wrapped_module_spec.rb +0 -261
- data/wiki/Customizing-pry.md +0 -397
- data/wiki/Home.md +0 -4
data/lib/pry/method.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'method_source'
|
3
4
|
|
4
5
|
class Pry
|
5
6
|
class << self
|
@@ -16,49 +17,52 @@ class Pry
|
|
16
17
|
|
17
18
|
# This class wraps the normal `Method` and `UnboundMethod` classes
|
18
19
|
# to provide extra functionality useful to Pry.
|
19
|
-
class Method
|
20
|
-
require 'pry/method/weird_method_locator'
|
21
|
-
require 'pry/method/disowned'
|
22
|
-
|
20
|
+
class Method # rubocop:disable Metrics/ClassLength
|
23
21
|
extend Helpers::BaseHelpers
|
22
|
+
extend Forwardable
|
23
|
+
|
24
24
|
include Helpers::BaseHelpers
|
25
|
-
include RbxMethod if rbx?
|
26
25
|
include Helpers::DocumentationHelpers
|
27
26
|
include CodeObject::Helpers
|
28
27
|
|
29
28
|
class << self
|
30
29
|
# Given a string representing a method name and optionally a binding to
|
31
|
-
# search in, find and return the requested method wrapped in a
|
32
|
-
# instance.
|
30
|
+
# search in, find and return the requested method wrapped in a
|
31
|
+
# `Pry::Method` instance.
|
33
32
|
#
|
34
|
-
# @param [String
|
35
|
-
# delegate to `from_binding` instead.
|
33
|
+
# @param [String] name The name of the method to retrieve.
|
36
34
|
# @param [Binding] target The context in which to search for the method.
|
37
35
|
# @param [Hash] options
|
38
|
-
# @option options [Boolean] :instance Look for an instance method if
|
39
|
-
# contain any context.
|
40
|
-
# @option options [Boolean] :methods Look for a bound/singleton method if
|
41
|
-
#
|
42
|
-
# @return [Pry::Method, nil] A `Pry::Method` instance containing the
|
43
|
-
# method, or `nil` if no method could be
|
44
|
-
|
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 = {})
|
45
44
|
if name.nil?
|
46
|
-
|
45
|
+
nil
|
47
46
|
elsif name.to_s =~ /(.+)\#(\S+)\Z/
|
48
|
-
context
|
47
|
+
context = Regexp.last_match(1)
|
48
|
+
meth_name = Regexp.last_match(2)
|
49
49
|
from_module(target.eval(context), meth_name, target)
|
50
|
+
elsif name.to_s =~ /(.+)(\[\])\Z/
|
51
|
+
context = Regexp.last_match(1)
|
52
|
+
meth_name = Regexp.last_match(2)
|
53
|
+
from_obj(target.eval(context), meth_name, target)
|
50
54
|
elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/
|
51
|
-
context
|
55
|
+
context = Regexp.last_match(1)
|
56
|
+
meth_name = Regexp.last_match(3)
|
52
57
|
from_obj(target.eval(context), meth_name, target)
|
53
58
|
elsif options[:instance]
|
54
59
|
from_module(target.eval("self"), name, target)
|
55
60
|
elsif options[:methods]
|
56
61
|
from_obj(target.eval("self"), name, target)
|
57
62
|
else
|
58
|
-
from_str(name, target, :
|
59
|
-
from_str(name, target, :
|
63
|
+
from_str(name, target, instance: true) ||
|
64
|
+
from_str(name, target, methods: true)
|
60
65
|
end
|
61
|
-
|
62
66
|
rescue Pry::RescuableException
|
63
67
|
nil
|
64
68
|
end
|
@@ -67,26 +71,33 @@ class Pry
|
|
67
71
|
# use it to instantiate a `Pry::Method`. Return `nil` if this isn't
|
68
72
|
# possible.
|
69
73
|
#
|
70
|
-
# @param [Binding]
|
74
|
+
# @param [Binding] binding
|
71
75
|
# @return [Pry::Method, nil]
|
72
76
|
#
|
73
|
-
def from_binding(
|
74
|
-
meth_name =
|
77
|
+
def from_binding(binding)
|
78
|
+
meth_name = binding.eval('::Kernel.__method__')
|
75
79
|
if [:__script__, nil].include?(meth_name)
|
76
80
|
nil
|
77
81
|
else
|
78
|
-
method =
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
90
101
|
else
|
91
102
|
method
|
92
103
|
end
|
@@ -100,11 +111,16 @@ class Pry
|
|
100
111
|
# @param [Symbol] method_type The type of method: :method or :instance_method
|
101
112
|
# @param [Binding] target The binding where the method is looked up.
|
102
113
|
# @return [Method, UnboundMethod] The 'refined' method object.
|
103
|
-
def lookup_method_via_binding(
|
114
|
+
def lookup_method_via_binding(
|
115
|
+
obj, method_name, method_type, target = TOPLEVEL_BINDING
|
116
|
+
)
|
104
117
|
Pry.current[:obj] = obj
|
105
118
|
Pry.current[:name] = method_name
|
106
119
|
receiver = obj.is_a?(Module) ? "Module" : "Kernel"
|
107
|
-
target.eval(
|
120
|
+
target.eval(
|
121
|
+
"::#{receiver}.instance_method(:#{method_type})" \
|
122
|
+
".bind(Pry.current[:obj]).call(Pry.current[:name])"
|
123
|
+
)
|
108
124
|
ensure
|
109
125
|
Pry.current[:obj] = Pry.current[:name] = nil
|
110
126
|
end
|
@@ -117,8 +133,10 @@ class Pry
|
|
117
133
|
# @param [String] name
|
118
134
|
# @param [Binding] target The binding where the method is looked up.
|
119
135
|
# @return [Pry::Method, nil]
|
120
|
-
def from_class(klass, name, target=TOPLEVEL_BINDING)
|
121
|
-
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
|
122
140
|
end
|
123
141
|
alias from_module from_class
|
124
142
|
|
@@ -130,24 +148,41 @@ class Pry
|
|
130
148
|
# @param [String] name
|
131
149
|
# @param [Binding] target The binding where the method is looked up.
|
132
150
|
# @return [Pry::Method, nil]
|
133
|
-
def from_obj(obj, name, target=TOPLEVEL_BINDING)
|
134
|
-
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
|
135
155
|
end
|
136
156
|
|
137
157
|
# Get all of the instance methods of a `Class` or `Module`
|
138
158
|
# @param [Class,Module] klass
|
139
159
|
# @param [Boolean] include_super Whether to include methods from ancestors.
|
140
160
|
# @return [Array[Pry::Method]]
|
141
|
-
def all_from_class(klass, include_super=true)
|
142
|
-
|
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
|
+
)
|
170
|
+
end
|
171
|
+
end
|
143
172
|
end
|
144
173
|
|
174
|
+
#
|
145
175
|
# Get all of the methods on an `Object`
|
176
|
+
#
|
146
177
|
# @param [Object] obj
|
147
|
-
#
|
178
|
+
#
|
179
|
+
# @param [Boolean] include_super
|
180
|
+
# indicates whether or not to include methods from ancestors.
|
181
|
+
#
|
148
182
|
# @return [Array[Pry::Method]]
|
149
|
-
|
150
|
-
|
183
|
+
#
|
184
|
+
def all_from_obj(obj, include_super = true)
|
185
|
+
all_from_class(singleton_class_of(obj), include_super)
|
151
186
|
end
|
152
187
|
|
153
188
|
# Get every `Class` and `Module`, in order, that will be checked when looking
|
@@ -155,10 +190,14 @@ class Pry
|
|
155
190
|
# @param [Object] obj
|
156
191
|
# @return [Array[Class, Module]]
|
157
192
|
def resolution_order(obj)
|
158
|
-
if Class === obj
|
193
|
+
if Class === obj # rubocop:disable Style/CaseEquality
|
159
194
|
singleton_class_resolution_order(obj) + instance_resolution_order(Class)
|
160
195
|
else
|
161
|
-
klass =
|
196
|
+
klass = begin
|
197
|
+
singleton_class_of(obj)
|
198
|
+
rescue StandardError
|
199
|
+
obj.class
|
200
|
+
end
|
162
201
|
instance_resolution_order(klass)
|
163
202
|
end
|
164
203
|
end
|
@@ -170,7 +209,7 @@ class Pry
|
|
170
209
|
# @return [Array[Class, Module]]
|
171
210
|
def instance_resolution_order(klass)
|
172
211
|
# include klass in case it is a singleton class,
|
173
|
-
([klass] + klass
|
212
|
+
([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq
|
174
213
|
end
|
175
214
|
|
176
215
|
def method_definition?(name, definition_line)
|
@@ -179,26 +218,17 @@ class Pry
|
|
179
218
|
end
|
180
219
|
|
181
220
|
def singleton_method_definition?(name, definition_line)
|
182
|
-
|
221
|
+
regexp =
|
222
|
+
/^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|
|
223
|
+
^def\s*self\.#{Regexp.escape(name)}/x
|
224
|
+
regexp =~ definition_line.strip
|
183
225
|
end
|
184
226
|
|
185
227
|
def instance_method_definition?(name, definition_line)
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
# See all_from_class and all_from_obj.
|
192
|
-
# If method_type is :instance_method, obj must be a `Class` or a `Module`
|
193
|
-
# If method_type is :method, obj can be any `Object`
|
194
|
-
#
|
195
|
-
# N.B. we pre-cache the visibility here to avoid O(N²) behaviour in "ls".
|
196
|
-
def all_from_common(obj, method_type, include_super=true)
|
197
|
-
%w(public protected private).map do |visibility|
|
198
|
-
safe_send(obj, :"#{visibility}_#{method_type}s", include_super).map do |method_name|
|
199
|
-
new(safe_send(obj, method_type, method_name), :visibility => visibility.to_sym)
|
200
|
-
end
|
201
|
-
end.flatten(1)
|
228
|
+
regexp =
|
229
|
+
/^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|
|
230
|
+
^def\s*#{Regexp.escape(name)}/x
|
231
|
+
regexp =~ definition_line.strip
|
202
232
|
end
|
203
233
|
|
204
234
|
# Get the singleton classes of superclasses that could define methods on
|
@@ -206,27 +236,38 @@ class Pry
|
|
206
236
|
# If a module is included at multiple points in the ancestry, only
|
207
237
|
# the lowest copy will be returned.
|
208
238
|
def singleton_class_resolution_order(klass)
|
209
|
-
|
210
|
-
|
211
|
-
|
239
|
+
ancestors = Pry::Method.safe_send(klass, :ancestors)
|
240
|
+
resolution_order = ancestors.grep(Class).flat_map do |anc|
|
241
|
+
[singleton_class_of(anc), *singleton_class_of(anc).included_modules]
|
242
|
+
end
|
212
243
|
|
213
244
|
resolution_order.reverse.uniq.reverse - Class.included_modules
|
214
245
|
end
|
215
246
|
|
216
|
-
def
|
247
|
+
def singleton_class_of(obj)
|
248
|
+
class << obj; self; end
|
249
|
+
rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ...
|
250
|
+
obj.class
|
251
|
+
end
|
217
252
|
end
|
218
253
|
|
219
|
-
#
|
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`.
|
220
259
|
#
|
221
260
|
# @param [::Method, UnboundMethod, Proc] method
|
222
261
|
# @param [Hash] known_info Can be used to pre-cache expensive to compute stuff.
|
223
262
|
# @return [Pry::Method]
|
224
|
-
def initialize(method, known_info={})
|
263
|
+
def initialize(method, known_info = {})
|
225
264
|
@method = method
|
226
265
|
@visibility = known_info[:visibility]
|
227
266
|
end
|
228
267
|
|
229
|
-
# 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
|
+
#
|
230
271
|
# @return [String]
|
231
272
|
def name
|
232
273
|
@method.name.to_s
|
@@ -263,26 +304,18 @@ class Pry
|
|
263
304
|
def source
|
264
305
|
@source ||= case source_type
|
265
306
|
when :c
|
266
|
-
|
267
|
-
if info and info.source
|
268
|
-
code = strip_comments_from_c_code(info.source)
|
269
|
-
end
|
307
|
+
c_source
|
270
308
|
when :ruby
|
271
|
-
|
272
|
-
# hacked version of source_location for rbx core methods, and
|
273
|
-
# our input buffer for methods defined in (pry)
|
274
|
-
file, line = *source_location
|
275
|
-
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file
|
276
|
-
|
277
|
-
begin
|
278
|
-
code = Pry::Code.from_file(file).expression_at(line)
|
279
|
-
rescue SyntaxError => e
|
280
|
-
raise MethodSource::SourceNotFoundError.new(e.message)
|
281
|
-
end
|
282
|
-
strip_leading_whitespace(code)
|
309
|
+
ruby_source
|
283
310
|
end
|
284
311
|
end
|
285
312
|
|
313
|
+
# Update the live copy of the method's source.
|
314
|
+
def redefine(source)
|
315
|
+
Patcher.new(self).patch_in_ram source
|
316
|
+
Pry::Method(owner.instance_method(name))
|
317
|
+
end
|
318
|
+
|
286
319
|
# Can we get the source code for this method?
|
287
320
|
# @return [Boolean]
|
288
321
|
def source?
|
@@ -293,20 +326,14 @@ class Pry
|
|
293
326
|
|
294
327
|
# @return [String, nil] The documentation for the method, or `nil` if it's
|
295
328
|
# unavailable.
|
296
|
-
# @raise [CommandError] Raises when the method was defined in the REPL.
|
297
329
|
def doc
|
298
|
-
@doc ||=
|
330
|
+
@doc ||=
|
331
|
+
case source_type
|
299
332
|
when :c
|
300
333
|
info = pry_doc_info
|
301
334
|
info.docstring if info
|
302
335
|
when :ruby
|
303
|
-
|
304
|
-
get_comment_content(core_doc)
|
305
|
-
elsif pry_method?
|
306
|
-
get_comment_content(doc_for_pry_method)
|
307
|
-
else
|
308
|
-
get_comment_content(@method.comment)
|
309
|
-
end
|
336
|
+
get_comment_content(comment)
|
310
337
|
end
|
311
338
|
end
|
312
339
|
|
@@ -316,20 +343,11 @@ class Pry
|
|
316
343
|
source_location.nil? ? :c : :ruby
|
317
344
|
end
|
318
345
|
|
319
|
-
def source_location
|
320
|
-
if @method.source_location && rbx?
|
321
|
-
file, line = @method.source_location
|
322
|
-
[RbxPath.convert_path_to_full(file), line]
|
323
|
-
else
|
324
|
-
@method.source_location
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
346
|
# @return [String, nil] The name of the file the method is defined in, or
|
329
347
|
# `nil` if the filename is unavailable.
|
330
348
|
def source_file
|
331
349
|
if source_location.nil?
|
332
|
-
if
|
350
|
+
if source_type == :c
|
333
351
|
info = pry_doc_info
|
334
352
|
info.file if info
|
335
353
|
end
|
@@ -353,33 +371,38 @@ class Pry
|
|
353
371
|
# @return [Symbol] The visibility of the method. May be `:public`,
|
354
372
|
# `:protected`, or `:private`.
|
355
373
|
def visibility
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
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
|
365
384
|
end
|
366
385
|
|
367
386
|
# @return [String] A representation of the method's signature, including its
|
368
387
|
# name and parameters. Optional and "rest" parameters are marked with `*`
|
369
|
-
# and block parameters with `&`.
|
370
|
-
# 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.
|
371
390
|
# Paraphrased from `awesome_print` gem.
|
372
391
|
def signature
|
373
392
|
if respond_to?(:parameters)
|
374
|
-
args = parameters.inject([]) do |
|
375
|
-
name ||= (
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
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
|
+
)
|
383
406
|
end
|
384
407
|
else
|
385
408
|
args = (1..arity.abs).map { |i| "arg#{i}" }
|
@@ -391,8 +414,8 @@ class Pry
|
|
391
414
|
|
392
415
|
# @return [Pry::Method, nil] The wrapped method that is called when you
|
393
416
|
# use "super" in the body of this method.
|
394
|
-
def super(times=1)
|
395
|
-
if
|
417
|
+
def super(times = 1)
|
418
|
+
if @method.is_a?(UnboundMethod)
|
396
419
|
sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times)
|
397
420
|
else
|
398
421
|
sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times)
|
@@ -405,12 +428,13 @@ class Pry
|
|
405
428
|
# before any aliasing, or `nil` if it can't be determined.
|
406
429
|
def original_name
|
407
430
|
return nil if source_type != :ruby
|
431
|
+
|
408
432
|
method_name_from_first_line(source.lines.first)
|
409
433
|
end
|
410
434
|
|
411
435
|
# @return [Boolean] Was the method defined outside a source file?
|
412
436
|
def dynamically_defined?
|
413
|
-
!!(source_file
|
437
|
+
!!(source_file && source_file =~ /(\(.*\))|<.*>/)
|
414
438
|
end
|
415
439
|
|
416
440
|
# @return [Boolean] Whether the method is unbound.
|
@@ -434,15 +458,14 @@ class Pry
|
|
434
458
|
end
|
435
459
|
|
436
460
|
# @return [Array<String>] All known aliases for the method.
|
437
|
-
# @note On Ruby 1.8 this method always returns an empty Array for methods
|
438
|
-
# implemented in C.
|
439
461
|
def aliases
|
440
462
|
owner = @method.owner
|
441
463
|
# Avoid using `to_sym` on {Method#name}, which returns a `String`, because
|
442
464
|
# it won't be garbage collected.
|
443
465
|
name = @method.name
|
444
466
|
|
445
|
-
|
467
|
+
all_methods_to_compare = owner.instance_methods | owner.private_instance_methods
|
468
|
+
alias_list = all_methods_to_compare.combination(2).select do |pair|
|
446
469
|
pair.include?(name) &&
|
447
470
|
owner.instance_method(pair.first) == owner.instance_method(pair.last)
|
448
471
|
end.flatten
|
@@ -457,30 +480,40 @@ class Pry
|
|
457
480
|
end
|
458
481
|
|
459
482
|
# @return [Boolean]
|
460
|
-
def ==(
|
461
|
-
if
|
462
|
-
|
463
|
-
|
464
|
-
@method == obj
|
465
|
-
end
|
483
|
+
def ==(other)
|
484
|
+
return other == @method if other.is_a?(Pry::Method)
|
485
|
+
|
486
|
+
@method == other
|
466
487
|
end
|
467
488
|
|
468
489
|
# @param [Class] klass
|
469
490
|
# @return [Boolean]
|
470
491
|
def is_a?(klass)
|
471
|
-
klass == Pry::Method
|
492
|
+
(klass == Pry::Method) || @method.is_a?(klass)
|
472
493
|
end
|
473
494
|
alias kind_of? is_a?
|
474
495
|
|
475
496
|
# @param [String, Symbol] method_name
|
476
497
|
# @return [Boolean]
|
477
|
-
def respond_to?(method_name)
|
478
|
-
super
|
498
|
+
def respond_to?(method_name, include_all = false)
|
499
|
+
super || @method.respond_to?(method_name, include_all)
|
479
500
|
end
|
480
501
|
|
481
502
|
# Delegate any unknown calls to the wrapped method.
|
482
503
|
def method_missing(method_name, *args, &block)
|
483
|
-
@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
|
513
|
+
end
|
514
|
+
|
515
|
+
def comment
|
516
|
+
Pry::Code.from_file(source_file).comment_describing(source_line)
|
484
517
|
end
|
485
518
|
|
486
519
|
private
|
@@ -488,48 +521,42 @@ class Pry
|
|
488
521
|
# @return [YARD::CodeObjects::MethodObject]
|
489
522
|
# @raise [CommandError] when the method can't be found or `pry-doc` isn't installed.
|
490
523
|
def pry_doc_info
|
491
|
-
if
|
492
|
-
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
|
+
)
|
493
530
|
else
|
494
531
|
fail_msg = "Cannot locate this method: #{name}."
|
495
|
-
if
|
496
|
-
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"
|
497
536
|
end
|
498
537
|
raise CommandError, fail_msg
|
499
538
|
end
|
500
539
|
end
|
501
540
|
|
502
|
-
# FIXME: a very similar method to this exists on WrappedModule: extract_doc_for_candidate
|
503
|
-
def doc_for_pry_method
|
504
|
-
_, line_num = source_location
|
505
|
-
|
506
|
-
buffer = ""
|
507
|
-
Pry.line_buffer[0..(line_num - 1)].each do |line|
|
508
|
-
# Add any line that is a valid ruby comment,
|
509
|
-
# but clear as soon as we hit a non comment line.
|
510
|
-
if (line =~ /^\s*#/) || (line =~ /^\s*$/)
|
511
|
-
buffer << line.lstrip
|
512
|
-
else
|
513
|
-
buffer.replace("")
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
buffer
|
518
|
-
end
|
519
|
-
|
520
541
|
# @param [Class, Module] ancestors The ancestors to investigate
|
521
542
|
# @return [Method] The unwrapped super-method
|
522
|
-
def super_using_ancestors(ancestors, times=1)
|
523
|
-
next_owner =
|
543
|
+
def super_using_ancestors(ancestors, times = 1)
|
544
|
+
next_owner = owner
|
524
545
|
times.times do
|
525
546
|
i = ancestors.index(next_owner) + 1
|
526
|
-
while ancestors[i] &&
|
547
|
+
while ancestors[i] &&
|
548
|
+
!(ancestors[i].method_defined?(name) ||
|
549
|
+
ancestors[i].private_method_defined?(name))
|
527
550
|
i += 1
|
528
551
|
end
|
529
|
-
next_owner = ancestors[i]
|
552
|
+
(next_owner = ancestors[i]) || (return nil)
|
530
553
|
end
|
531
554
|
|
532
|
-
|
555
|
+
begin
|
556
|
+
safe_send(next_owner, :instance_method, name)
|
557
|
+
rescue StandardError
|
558
|
+
nil
|
559
|
+
end
|
533
560
|
end
|
534
561
|
|
535
562
|
# @param [String] first_ln The first line of a method definition.
|
@@ -537,7 +564,7 @@ class Pry
|
|
537
564
|
def method_name_from_first_line(first_ln)
|
538
565
|
return nil if first_ln.strip !~ /^def /
|
539
566
|
|
540
|
-
tokens =
|
567
|
+
tokens = SyntaxHighlighter.tokenize(first_ln)
|
541
568
|
tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
|
542
569
|
tokens.each_cons(2) do |t1, t2|
|
543
570
|
if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
|
@@ -547,5 +574,27 @@ class Pry
|
|
547
574
|
|
548
575
|
nil
|
549
576
|
end
|
577
|
+
|
578
|
+
def c_source
|
579
|
+
info = pry_doc_info
|
580
|
+
strip_comments_from_c_code(info.source) if info && info.source
|
581
|
+
end
|
582
|
+
|
583
|
+
def ruby_source
|
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)`.
|
587
|
+
file, line = *source_location
|
588
|
+
unless file
|
589
|
+
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!"
|
590
|
+
end
|
591
|
+
|
592
|
+
begin
|
593
|
+
code = Pry::Code.from_file(file).expression_at(line)
|
594
|
+
rescue SyntaxError => e
|
595
|
+
raise MethodSource::SourceNotFoundError, e.message
|
596
|
+
end
|
597
|
+
strip_leading_whitespace(code)
|
598
|
+
end
|
550
599
|
end
|
551
600
|
end
|