pry 0.9.12.6 → 0.10.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +702 -0
- data/LICENSE +2 -2
- data/{README.markdown → README.md} +37 -31
- data/lib/pry.rb +38 -151
- data/lib/pry/cli.rb +35 -17
- data/lib/pry/code.rb +24 -63
- data/lib/pry/code/code_file.rb +103 -0
- data/lib/pry/code/code_range.rb +2 -1
- data/lib/pry/code/loc.rb +2 -2
- data/lib/pry/code_object.rb +40 -21
- data/lib/pry/color_printer.rb +55 -0
- data/lib/pry/command.rb +12 -9
- data/lib/pry/command_set.rb +81 -38
- data/lib/pry/commands.rb +1 -1
- data/lib/pry/commands/amend_line.rb +2 -2
- data/lib/pry/commands/bang.rb +1 -1
- data/lib/pry/commands/cat.rb +11 -2
- data/lib/pry/commands/cat/exception_formatter.rb +5 -6
- data/lib/pry/commands/cat/file_formatter.rb +15 -32
- data/lib/pry/commands/cd.rb +14 -3
- data/lib/pry/commands/change_inspector.rb +27 -0
- data/lib/pry/commands/change_prompt.rb +26 -0
- data/lib/pry/commands/code_collector.rb +4 -4
- data/lib/pry/commands/easter_eggs.rb +3 -3
- data/lib/pry/commands/edit.rb +10 -22
- data/lib/pry/commands/edit/exception_patcher.rb +2 -2
- data/lib/pry/commands/edit/file_and_line_locator.rb +0 -2
- data/lib/pry/commands/exit_program.rb +0 -1
- data/lib/pry/commands/find_method.rb +16 -22
- data/lib/pry/commands/gem_install.rb +5 -2
- data/lib/pry/commands/gem_open.rb +1 -1
- data/lib/pry/commands/gist.rb +10 -11
- data/lib/pry/commands/help.rb +14 -14
- data/lib/pry/commands/hist.rb +27 -8
- data/lib/pry/commands/install_command.rb +14 -12
- data/lib/pry/commands/list_inspectors.rb +35 -0
- data/lib/pry/commands/list_prompts.rb +35 -0
- data/lib/pry/commands/ls.rb +72 -296
- data/lib/pry/commands/ls/constants.rb +47 -0
- data/lib/pry/commands/ls/formatter.rb +49 -0
- data/lib/pry/commands/ls/globals.rb +48 -0
- data/lib/pry/commands/ls/grep.rb +21 -0
- data/lib/pry/commands/ls/instance_vars.rb +39 -0
- data/lib/pry/commands/ls/interrogatable.rb +18 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
- data/lib/pry/commands/ls/local_names.rb +35 -0
- data/lib/pry/commands/ls/local_vars.rb +39 -0
- data/lib/pry/commands/ls/ls_entity.rb +70 -0
- data/lib/pry/commands/ls/methods.rb +57 -0
- data/lib/pry/commands/ls/methods_helper.rb +46 -0
- data/lib/pry/commands/ls/self_methods.rb +32 -0
- data/lib/pry/commands/play.rb +44 -10
- data/lib/pry/commands/pry_backtrace.rb +1 -2
- data/lib/pry/commands/raise_up.rb +2 -2
- data/lib/pry/commands/reload_code.rb +16 -19
- data/lib/pry/commands/ri.rb +7 -3
- data/lib/pry/commands/shell_command.rb +18 -13
- data/lib/pry/commands/shell_mode.rb +2 -4
- data/lib/pry/commands/show_doc.rb +5 -0
- data/lib/pry/commands/show_info.rb +8 -13
- data/lib/pry/commands/show_source.rb +15 -3
- data/lib/pry/commands/simple_prompt.rb +1 -1
- data/lib/pry/commands/toggle_color.rb +8 -4
- data/lib/pry/commands/watch_expression.rb +105 -0
- data/lib/pry/commands/watch_expression/expression.rb +38 -0
- data/lib/pry/commands/whereami.rb +18 -10
- data/lib/pry/commands/wtf.rb +3 -3
- data/lib/pry/config.rb +20 -254
- data/lib/pry/config/behavior.rb +139 -0
- data/lib/pry/config/convenience.rb +26 -0
- data/lib/pry/config/default.rb +165 -0
- data/lib/pry/core_extensions.rb +31 -21
- data/lib/pry/editor.rb +107 -103
- data/lib/pry/exceptions.rb +77 -0
- data/lib/pry/helpers/base_helpers.rb +22 -109
- data/lib/pry/helpers/command_helpers.rb +10 -8
- data/lib/pry/helpers/documentation_helpers.rb +1 -2
- data/lib/pry/helpers/text.rb +4 -5
- data/lib/pry/history.rb +46 -45
- data/lib/pry/history_array.rb +6 -1
- data/lib/pry/hooks.rb +9 -29
- data/lib/pry/indent.rb +6 -6
- data/lib/pry/input_completer.rb +242 -0
- data/lib/pry/input_lock.rb +132 -0
- data/lib/pry/inspector.rb +27 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method.rb +82 -87
- data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +41 -38
- data/lib/pry/module_candidate.rb +4 -14
- data/lib/pry/object_path.rb +82 -0
- data/lib/pry/output.rb +50 -0
- data/lib/pry/pager.rb +191 -47
- data/lib/pry/plugins.rb +1 -1
- data/lib/pry/prompt.rb +26 -0
- data/lib/pry/pry_class.rb +149 -230
- data/lib/pry/pry_instance.rb +302 -413
- data/lib/pry/rbx_path.rb +1 -1
- data/lib/pry/repl.rb +202 -0
- data/lib/pry/repl_file_loader.rb +20 -26
- data/lib/pry/rubygem.rb +13 -5
- data/lib/pry/terminal.rb +2 -1
- data/lib/pry/test/helper.rb +26 -41
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +45 -59
- metadata +61 -224
- data/.document +0 -2
- data/.gitignore +0 -16
- data/.travis.yml +0 -25
- data/.yardopts +0 -1
- data/CHANGELOG +0 -534
- data/CONTRIBUTORS +0 -55
- data/Gemfile +0 -12
- data/Rakefile +0 -140
- data/TODO +0 -117
- data/lib/pry/completion.rb +0 -321
- data/lib/pry/custom_completions.rb +0 -6
- data/lib/pry/rbx_method.rb +0 -13
- data/man/pry.1 +0 -195
- data/man/pry.1.html +0 -204
- data/man/pry.1.ronn +0 -141
- data/pry.gemspec +0 -29
- 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 -241
- 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 -515
- 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
@@ -0,0 +1,27 @@
|
|
1
|
+
class Pry::Inspector
|
2
|
+
MAP = {
|
3
|
+
"default" => {
|
4
|
+
value: Pry::DEFAULT_PRINT,
|
5
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip!)
|
6
|
+
The default Pry inspector. It has paging and color support, and uses
|
7
|
+
pretty_inspect when printing an object.
|
8
|
+
DESCRIPTION
|
9
|
+
},
|
10
|
+
|
11
|
+
"simple" => {
|
12
|
+
value: Pry::SIMPLE_PRINT,
|
13
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
14
|
+
A simple inspector that uses #puts and #inspect when printing an
|
15
|
+
object. It has no pager, color, or pretty_inspect support.
|
16
|
+
DESCRIPTION
|
17
|
+
},
|
18
|
+
|
19
|
+
"clipped" => {
|
20
|
+
value: Pry::CLIPPED_PRINT,
|
21
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
22
|
+
The clipped inspector has the same features as the 'simple' inspector
|
23
|
+
but prints large objects as a smaller string.
|
24
|
+
DESCRIPTION
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# {Pry::LastException} is a proxy class who wraps an Exception object for
|
3
|
+
# {Pry#last_exception}. it extends the exception object with methods that
|
4
|
+
# help pry commands be useful.
|
5
|
+
#
|
6
|
+
# the original exception object is not modified and method calls are forwarded
|
7
|
+
# to the wrapped exception object.
|
8
|
+
#
|
9
|
+
class Pry::LastException < BasicObject
|
10
|
+
attr_accessor :bt_index
|
11
|
+
|
12
|
+
def initialize(e)
|
13
|
+
@e = e
|
14
|
+
@bt_index = 0
|
15
|
+
@file, @line = bt_source_location_for(0)
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args, &block)
|
19
|
+
if @e.respond_to?(name)
|
20
|
+
@e.public_send(name, *args, &block)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to_missing?(name, include_private = false)
|
27
|
+
@e.respond_to?(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# @return [String]
|
32
|
+
# returns the path to a file for the current backtrace. see {#bt_index}.
|
33
|
+
#
|
34
|
+
def file
|
35
|
+
@file
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# @return [Fixnum]
|
40
|
+
# returns the line for the current backtrace. see {#bt_index}.
|
41
|
+
#
|
42
|
+
def line
|
43
|
+
@line
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Exception]
|
47
|
+
# returns the wrapped exception
|
48
|
+
#
|
49
|
+
def wrapped_exception
|
50
|
+
@e
|
51
|
+
end
|
52
|
+
|
53
|
+
def bt_source_location_for(index)
|
54
|
+
backtrace[index] =~ /(.*):(\d+)/
|
55
|
+
[$1, $2.to_i]
|
56
|
+
end
|
57
|
+
|
58
|
+
def inc_bt_index
|
59
|
+
@bt_index = (@bt_index + 1) % backtrace.size
|
60
|
+
end
|
61
|
+
end
|
data/lib/pry/method.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
require 'pry/helpers/documentation_helpers'
|
3
2
|
|
4
3
|
class Pry
|
@@ -19,10 +18,10 @@ class Pry
|
|
19
18
|
class Method
|
20
19
|
require 'pry/method/weird_method_locator'
|
21
20
|
require 'pry/method/disowned'
|
21
|
+
require 'pry/method/patcher'
|
22
22
|
|
23
23
|
extend Helpers::BaseHelpers
|
24
24
|
include Helpers::BaseHelpers
|
25
|
-
include RbxMethod if rbx?
|
26
25
|
include Helpers::DocumentationHelpers
|
27
26
|
include CodeObject::Helpers
|
28
27
|
|
@@ -31,8 +30,7 @@ class Pry
|
|
31
30
|
# search in, find and return the requested method wrapped in a `Pry::Method`
|
32
31
|
# 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
36
|
# @option options [Boolean] :instance Look for an instance method if `name` doesn't
|
@@ -40,13 +38,16 @@ class Pry
|
|
40
38
|
# @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't
|
41
39
|
# contain any context.
|
42
40
|
# @return [Pry::Method, nil] A `Pry::Method` instance containing the requested
|
43
|
-
# method, or `nil` if no method could be located matching the parameters.
|
41
|
+
# method, or `nil` if name is `nil` or no method could be located matching the parameters.
|
44
42
|
def from_str(name, target=TOPLEVEL_BINDING, options={})
|
45
43
|
if name.nil?
|
46
|
-
|
44
|
+
nil
|
47
45
|
elsif name.to_s =~ /(.+)\#(\S+)\Z/
|
48
46
|
context, meth_name = $1, $2
|
49
47
|
from_module(target.eval(context), meth_name, target)
|
48
|
+
elsif name.to_s =~ /(.+)(\[\])\Z/
|
49
|
+
context, meth_name = $1, $2
|
50
|
+
from_obj(target.eval(context), meth_name, target)
|
50
51
|
elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/
|
51
52
|
context, meth_name = $1, $3
|
52
53
|
from_obj(target.eval(context), meth_name, target)
|
@@ -139,15 +140,34 @@ class Pry
|
|
139
140
|
# @param [Boolean] include_super Whether to include methods from ancestors.
|
140
141
|
# @return [Array[Pry::Method]]
|
141
142
|
def all_from_class(klass, include_super=true)
|
142
|
-
|
143
|
+
%w(public protected private).map do |visibility|
|
144
|
+
safe_send(klass, :"#{visibility}_instance_methods", include_super).map do |method_name|
|
145
|
+
new(safe_send(klass, :instance_method, method_name), :visibility => visibility.to_sym)
|
146
|
+
end
|
147
|
+
end.flatten(1)
|
143
148
|
end
|
144
149
|
|
150
|
+
#
|
145
151
|
# Get all of the methods on an `Object`
|
152
|
+
#
|
146
153
|
# @param [Object] obj
|
147
|
-
#
|
154
|
+
#
|
155
|
+
# @param [Boolean] include_super
|
156
|
+
# indicates whether or not to include methods from ancestors.
|
157
|
+
#
|
148
158
|
# @return [Array[Pry::Method]]
|
159
|
+
#
|
149
160
|
def all_from_obj(obj, include_super=true)
|
150
|
-
|
161
|
+
all_from_class(singleton_class_of(obj), include_super)
|
162
|
+
end
|
163
|
+
|
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)
|
151
171
|
end
|
152
172
|
|
153
173
|
# Get every `Class` and `Module`, in order, that will be checked when looking
|
@@ -158,7 +178,7 @@ class Pry
|
|
158
178
|
if Class === obj
|
159
179
|
singleton_class_resolution_order(obj) + instance_resolution_order(Class)
|
160
180
|
else
|
161
|
-
klass =
|
181
|
+
klass = singleton_class_of(obj) rescue obj.class
|
162
182
|
instance_resolution_order(klass)
|
163
183
|
end
|
164
184
|
end
|
@@ -170,7 +190,7 @@ class Pry
|
|
170
190
|
# @return [Array[Class, Module]]
|
171
191
|
def instance_resolution_order(klass)
|
172
192
|
# include klass in case it is a singleton class,
|
173
|
-
([klass] + klass
|
193
|
+
([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq
|
174
194
|
end
|
175
195
|
|
176
196
|
def method_definition?(name, definition_line)
|
@@ -179,26 +199,11 @@ class Pry
|
|
179
199
|
end
|
180
200
|
|
181
201
|
def singleton_method_definition?(name, definition_line)
|
182
|
-
/^define_singleton_method\(?\s*[:\"\']#{name}|^def\s*self\.#{name}/ =~ definition_line.strip
|
202
|
+
/^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*self\.#{Regexp.escape(name)}/ =~ definition_line.strip
|
183
203
|
end
|
184
204
|
|
185
205
|
def instance_method_definition?(name, definition_line)
|
186
|
-
/^define_method\(?\s*[:\"\']#{name}|^def\s*#{name}/ =~ definition_line.strip
|
187
|
-
end
|
188
|
-
|
189
|
-
private
|
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)
|
206
|
+
/^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*#{Regexp.escape(name)}/ =~ definition_line.strip
|
202
207
|
end
|
203
208
|
|
204
209
|
# Get the singleton classes of superclasses that could define methods on
|
@@ -206,14 +211,21 @@ class Pry
|
|
206
211
|
# If a module is included at multiple points in the ancestry, only
|
207
212
|
# the lowest copy will be returned.
|
208
213
|
def singleton_class_resolution_order(klass)
|
209
|
-
|
210
|
-
|
211
|
-
|
214
|
+
ancestors = Pry::Method.safe_send(klass, :ancestors)
|
215
|
+
resolution_order = ancestors.grep(Class).map do |anc|
|
216
|
+
[singleton_class_of(anc), *singleton_class_of(anc).included_modules]
|
217
|
+
end.flatten(1)
|
212
218
|
|
213
219
|
resolution_order.reverse.uniq.reverse - Class.included_modules
|
214
220
|
end
|
215
221
|
|
216
|
-
def
|
222
|
+
def singleton_class_of(obj)
|
223
|
+
begin
|
224
|
+
class << obj; self; end
|
225
|
+
rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ...
|
226
|
+
obj.class
|
227
|
+
end
|
228
|
+
end
|
217
229
|
end
|
218
230
|
|
219
231
|
# A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`.
|
@@ -263,26 +275,18 @@ class Pry
|
|
263
275
|
def source
|
264
276
|
@source ||= case source_type
|
265
277
|
when :c
|
266
|
-
|
267
|
-
if info and info.source
|
268
|
-
code = strip_comments_from_c_code(info.source)
|
269
|
-
end
|
278
|
+
c_source
|
270
279
|
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)
|
280
|
+
ruby_source
|
283
281
|
end
|
284
282
|
end
|
285
283
|
|
284
|
+
# Update the live copy of the method's source.
|
285
|
+
def redefine(source)
|
286
|
+
Patcher.new(self).patch_in_ram source
|
287
|
+
Pry::Method(owner.instance_method(name))
|
288
|
+
end
|
289
|
+
|
286
290
|
# Can we get the source code for this method?
|
287
291
|
# @return [Boolean]
|
288
292
|
def source?
|
@@ -293,20 +297,13 @@ class Pry
|
|
293
297
|
|
294
298
|
# @return [String, nil] The documentation for the method, or `nil` if it's
|
295
299
|
# unavailable.
|
296
|
-
# @raise [CommandError] Raises when the method was defined in the REPL.
|
297
300
|
def doc
|
298
301
|
@doc ||= case source_type
|
299
302
|
when :c
|
300
303
|
info = pry_doc_info
|
301
304
|
info.docstring if info
|
302
305
|
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
|
306
|
+
get_comment_content(comment)
|
310
307
|
end
|
311
308
|
end
|
312
309
|
|
@@ -316,15 +313,6 @@ class Pry
|
|
316
313
|
source_location.nil? ? :c : :ruby
|
317
314
|
end
|
318
315
|
|
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
316
|
# @return [String, nil] The name of the file the method is defined in, or
|
329
317
|
# `nil` if the filename is unavailable.
|
330
318
|
def source_file
|
@@ -434,15 +422,14 @@ class Pry
|
|
434
422
|
end
|
435
423
|
|
436
424
|
# @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
425
|
def aliases
|
440
426
|
owner = @method.owner
|
441
427
|
# Avoid using `to_sym` on {Method#name}, which returns a `String`, because
|
442
428
|
# it won't be garbage collected.
|
443
429
|
name = @method.name
|
444
430
|
|
445
|
-
|
431
|
+
all_methods_to_compare = owner.instance_methods | owner.private_instance_methods
|
432
|
+
alias_list = all_methods_to_compare.combination(2).select do |pair|
|
446
433
|
pair.include?(name) &&
|
447
434
|
owner.instance_method(pair.first) == owner.instance_method(pair.last)
|
448
435
|
end.flatten
|
@@ -483,6 +470,10 @@ class Pry
|
|
483
470
|
@method.send(method_name, *args, &block)
|
484
471
|
end
|
485
472
|
|
473
|
+
def comment
|
474
|
+
Pry::Code.from_file(source_file).comment_describing(source_line)
|
475
|
+
end
|
476
|
+
|
486
477
|
private
|
487
478
|
|
488
479
|
# @return [YARD::CodeObjects::MethodObject]
|
@@ -492,31 +483,13 @@ class Pry
|
|
492
483
|
Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
|
493
484
|
else
|
494
485
|
fail_msg = "Cannot locate this method: #{name}."
|
495
|
-
if
|
486
|
+
if mri?
|
496
487
|
fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.'
|
497
488
|
end
|
498
489
|
raise CommandError, fail_msg
|
499
490
|
end
|
500
491
|
end
|
501
492
|
|
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
493
|
# @param [Class, Module] ancestors The ancestors to investigate
|
521
494
|
# @return [Method] The unwrapped super-method
|
522
495
|
def super_using_ancestors(ancestors, times=1)
|
@@ -547,5 +520,27 @@ class Pry
|
|
547
520
|
|
548
521
|
nil
|
549
522
|
end
|
523
|
+
|
524
|
+
def c_source
|
525
|
+
info = pry_doc_info
|
526
|
+
if info and info.source
|
527
|
+
strip_comments_from_c_code(info.source)
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
def ruby_source
|
532
|
+
# clone of MethodSource.source_helper that knows to use our
|
533
|
+
# hacked version of source_location for rbx core methods, and
|
534
|
+
# our input buffer for methods defined in (pry)
|
535
|
+
file, line = *source_location
|
536
|
+
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file
|
537
|
+
|
538
|
+
begin
|
539
|
+
code = Pry::Code.from_file(file).expression_at(line)
|
540
|
+
rescue SyntaxError => e
|
541
|
+
raise MethodSource::SourceNotFoundError.new(e.message)
|
542
|
+
end
|
543
|
+
strip_leading_whitespace(code)
|
544
|
+
end
|
550
545
|
end
|
551
546
|
end
|
@@ -1,37 +1,38 @@
|
|
1
1
|
class Pry
|
2
|
-
class
|
3
|
-
class
|
4
|
-
attr_accessor :
|
5
|
-
attr_accessor :code_object
|
2
|
+
class Method
|
3
|
+
class Patcher
|
4
|
+
attr_accessor :method
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
@@source_cache = {}
|
7
|
+
|
8
|
+
def initialize(method)
|
9
|
+
@method = method
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.code_for(filename)
|
13
|
+
@@source_cache[filename]
|
10
14
|
end
|
11
15
|
|
12
16
|
# perform the patch
|
13
|
-
def
|
14
|
-
if
|
17
|
+
def patch_in_ram(source)
|
18
|
+
if method.alias?
|
15
19
|
with_method_transaction do
|
16
|
-
|
20
|
+
redefine source
|
17
21
|
end
|
18
22
|
else
|
19
|
-
|
23
|
+
redefine source
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
27
|
private
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def redefine(source)
|
30
|
+
@@source_cache[cache_key] = source
|
31
|
+
TOPLEVEL_BINDING.eval wrap(source), cache_key
|
27
32
|
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
def adjusted_lines
|
32
|
-
lines = code_object.source.lines.to_a
|
33
|
-
lines[0] = definition_line_for_owner(lines.first)
|
34
|
-
lines
|
34
|
+
def cache_key
|
35
|
+
"pry-redefined(0x#{method.owner.object_id.to_s(16)}##{method.name})"
|
35
36
|
end
|
36
37
|
|
37
38
|
# Run some code ensuring that at the end target#meth_name will not have changed.
|
@@ -45,17 +46,17 @@ class Pry
|
|
45
46
|
# @param [Module] target The owner of the method
|
46
47
|
|
47
48
|
def with_method_transaction
|
48
|
-
temp_name = "__pry_#{
|
49
|
-
|
50
|
-
|
51
|
-
alias_method temp_name,
|
49
|
+
temp_name = "__pry_#{method.original_name}__"
|
50
|
+
method = self.method
|
51
|
+
method.owner.class_eval do
|
52
|
+
alias_method temp_name, method.original_name
|
52
53
|
yield
|
53
|
-
alias_method
|
54
|
-
alias_method
|
54
|
+
alias_method method.name, method.original_name
|
55
|
+
alias_method method.original_name, temp_name
|
55
56
|
end
|
56
57
|
|
57
58
|
ensure
|
58
|
-
|
59
|
+
method.send(:remove_method, temp_name) rescue nil
|
59
60
|
end
|
60
61
|
|
61
62
|
# Update the definition line so that it can be eval'd directly on the Method's
|
@@ -68,13 +69,13 @@ class Pry
|
|
68
69
|
# This is necessarily done by String manipulation because we can't find out what
|
69
70
|
# syntax is needed for the argument list by ruby-level introspection.
|
70
71
|
#
|
71
|
-
# @param String
|
72
|
-
# @return String The new definition line. e.g. def foo(bar, baz=1)
|
73
|
-
def
|
74
|
-
if line =~
|
75
|
-
"def #{
|
72
|
+
# @param [String] line The original definition line. e.g. def self.foo(bar, baz=1)
|
73
|
+
# @return [String] The new definition line. e.g. def foo(bar, baz=1)
|
74
|
+
def definition_for_owner(line)
|
75
|
+
if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/
|
76
|
+
"def #{method.original_name}#{$'}"
|
76
77
|
else
|
77
|
-
raise CommandError, "Could not find original `def #{
|
78
|
+
raise CommandError, "Could not find original `def #{method.original_name}` line to patch."
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
@@ -87,15 +88,17 @@ class Pry
|
|
87
88
|
|
88
89
|
# Update the source code so that when it has the right owner when eval'd.
|
89
90
|
#
|
90
|
-
# This (combined with
|
91
|
+
# This (combined with definition_for_owner) is backup for the case that
|
91
92
|
# wrap_for_nesting fails, to ensure that the method will stil be defined in
|
92
93
|
# the correct place.
|
93
94
|
#
|
94
95
|
# @param [String] source The source to wrap
|
95
96
|
# @return [String]
|
96
97
|
def wrap_for_owner(source)
|
97
|
-
Pry.current[:pry_owner] =
|
98
|
-
|
98
|
+
Pry.current[:pry_owner] = method.owner
|
99
|
+
owner_source = definition_for_owner(source)
|
100
|
+
visibility_fix = "#{method.visibility.to_s} #{method.name.to_sym.inspect}"
|
101
|
+
"Pry.current[:pry_owner].class_eval do; #{owner_source}\n#{visibility_fix}\nend"
|
99
102
|
end
|
100
103
|
|
101
104
|
# Update the new source code to have the correct Module.nesting.
|
@@ -111,10 +114,10 @@ class Pry
|
|
111
114
|
# @param [String] source The source to wrap.
|
112
115
|
# @return [String]
|
113
116
|
def wrap_for_nesting(source)
|
114
|
-
nesting = Pry::Code.from_file(
|
117
|
+
nesting = Pry::Code.from_file(method.source_file).nesting_at(method.source_line)
|
115
118
|
|
116
|
-
(nesting + [source] + nesting.map{ "end" } + [""]).join("
|
117
|
-
rescue Pry::Indent::UnparseableNestingError
|
119
|
+
(nesting + [source] + nesting.map{ "end" } + [""]).join(";")
|
120
|
+
rescue Pry::Indent::UnparseableNestingError
|
118
121
|
source
|
119
122
|
end
|
120
123
|
end
|