pry 0.12.2-java → 0.13.0-java
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 +110 -1
- data/LICENSE +1 -1
- data/README.md +331 -269
- data/bin/pry +5 -0
- data/lib/pry.rb +133 -119
- data/lib/pry/basic_object.rb +8 -4
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +40 -31
- data/lib/pry/code.rb +39 -27
- data/lib/pry/code/code_file.rb +28 -24
- data/lib/pry/code/code_range.rb +4 -2
- data/lib/pry/code/loc.rb +15 -8
- data/lib/pry/code_object.rb +40 -38
- data/lib/pry/color_printer.rb +47 -46
- data/lib/pry/command.rb +166 -369
- data/lib/pry/command_set.rb +76 -73
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -81
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat.rb +61 -54
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +71 -60
- data/lib/pry/commands/cat/file_formatter.rb +55 -49
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +44 -39
- data/lib/pry/commands/clear_screen.rb +16 -10
- data/lib/pry/commands/code_collector.rb +148 -133
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +19 -30
- data/lib/pry/commands/edit.rb +184 -161
- 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/exit.rb +39 -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 -160
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -150
- data/lib/pry/commands/import_set.rb +20 -16
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls.rb +124 -102
- data/lib/pry/commands/ls/constants.rb +59 -42
- data/lib/pry/commands/ls/formatter.rb +50 -46
- data/lib/pry/commands/ls/globals.rb +38 -34
- data/lib/pry/commands/ls/grep.rb +17 -13
- data/lib/pry/commands/ls/instance_vars.rb +29 -27
- 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 -22
- data/lib/pry/commands/ls/local_vars.rb +38 -28
- data/lib/pry/commands/ls/ls_entity.rb +47 -51
- data/lib/pry/commands/ls/methods.rb +44 -43
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -22
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +93 -82
- data/lib/pry/commands/pry_backtrace.rb +24 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +27 -22
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +55 -45
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +51 -51
- data/lib/pry/commands/shell_mode.rb +21 -17
- data/lib/pry/commands/show_doc.rb +81 -68
- data/lib/pry/commands/show_info.rb +189 -171
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +109 -45
- 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.rb +89 -86
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/whereami.rb +156 -148
- data/lib/pry/commands/wtf.rb +75 -50
- data/lib/pry/config.rb +311 -25
- 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/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +9 -7
- data/lib/pry/editor.rb +48 -21
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -16
- data/lib/pry/forwardable.rb +5 -1
- data/lib/pry/helpers.rb +2 -0
- data/lib/pry/helpers/base_helpers.rb +68 -197
- data/lib/pry/helpers/command_helpers.rb +50 -61
- data/lib/pry/helpers/documentation_helpers.rb +20 -13
- data/lib/pry/helpers/options_helpers.rb +14 -7
- data/lib/pry/helpers/platform.rb +7 -5
- data/lib/pry/helpers/table.rb +33 -26
- data/lib/pry/helpers/text.rb +17 -14
- data/lib/pry/history.rb +48 -56
- data/lib/pry/hooks.rb +21 -12
- data/lib/pry/indent.rb +54 -50
- data/lib/pry/input_completer.rb +248 -230
- data/lib/pry/input_lock.rb +8 -9
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method.rb +141 -94
- data/lib/pry/method/disowned.rb +16 -4
- data/lib/pry/method/patcher.rb +12 -3
- data/lib/pry/method/weird_method_locator.rb +68 -44
- data/lib/pry/object_path.rb +33 -25
- data/lib/pry/output.rb +121 -35
- data/lib/pry/pager.rb +41 -42
- data/lib/pry/plugins.rb +25 -8
- data/lib/pry/prompt.rb +123 -54
- data/lib/pry/pry_class.rb +61 -98
- data/lib/pry/pry_instance.rb +217 -215
- data/lib/pry/repl.rb +18 -22
- data/lib/pry/repl_file_loader.rb +27 -21
- data/lib/pry/ring.rb +11 -6
- data/lib/pry/slop.rb +574 -563
- data/lib/pry/slop/commands.rb +164 -169
- data/lib/pry/slop/option.rb +172 -168
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable.rb +59 -61
- data/lib/pry/testable/evalable.rb +21 -12
- data/lib/pry/testable/mockable.rb +18 -10
- data/lib/pry/testable/pry_tester.rb +71 -56
- data/lib/pry/testable/utility.rb +29 -21
- data/lib/pry/testable/variables.rb +49 -43
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +27 -0
- data/lib/pry/wrapped_module.rb +51 -42
- data/lib/pry/wrapped_module/candidate.rb +21 -14
- metadata +31 -30
- data/lib/pry/commands.rb +0 -6
- 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/gem_readme.rb +0 -25
- data/lib/pry/commands/gem_search.rb +0 -40
- data/lib/pry/commands/gem_stats.rb +0 -83
- data/lib/pry/commands/gist.rb +0 -102
- data/lib/pry/commands/install_command.rb +0 -54
- data/lib/pry/config/behavior.rb +0 -255
- data/lib/pry/config/convenience.rb +0 -28
- data/lib/pry/config/default.rb +0 -159
- data/lib/pry/config/memoization.rb +0 -48
- data/lib/pry/platform.rb +0 -91
- data/lib/pry/rubygem.rb +0 -84
- data/lib/pry/terminal.rb +0 -91
data/lib/pry/input_lock.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
4
|
# There is one InputLock per input (such as STDIN) as two REPLs on the same
|
3
5
|
# input makes things delirious. InputLock serializes accesses to the input so
|
4
6
|
# that threads to not conflict with each other. The latest thread to request
|
5
7
|
# ownership of the input wins.
|
6
8
|
class InputLock
|
7
|
-
class Interrupt < Exception; end
|
9
|
+
class Interrupt < Exception; end # rubocop:disable Lint/InheritException
|
8
10
|
|
9
11
|
class << self
|
10
12
|
attr_accessor :input_locks
|
@@ -33,7 +35,7 @@ class Pry
|
|
33
35
|
|
34
36
|
# Adds ourselves to the ownership list. The last one in the list may access
|
35
37
|
# the input through interruptible_region().
|
36
|
-
def __with_ownership
|
38
|
+
def __with_ownership
|
37
39
|
@mutex.synchronize do
|
38
40
|
# Three cases:
|
39
41
|
# 1) There are no owners, in this case we are good to go.
|
@@ -56,8 +58,7 @@ class Pry
|
|
56
58
|
@owners << Thread.current
|
57
59
|
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
+
yield
|
61
62
|
ensure
|
62
63
|
@mutex.synchronize do
|
63
64
|
# We are releasing any desire to have the input ownership by removing
|
@@ -74,7 +75,7 @@ class Pry
|
|
74
75
|
def with_ownership(&block)
|
75
76
|
# If we are in a nested with_ownership() call (nested pry context), we do nothing.
|
76
77
|
nested = @mutex.synchronize { @owners.include?(Thread.current) }
|
77
|
-
nested ?
|
78
|
+
nested ? yield : __with_ownership(&block)
|
78
79
|
end
|
79
80
|
|
80
81
|
def enter_interruptible_region
|
@@ -104,14 +105,13 @@ class Pry
|
|
104
105
|
retry
|
105
106
|
end
|
106
107
|
|
107
|
-
def interruptible_region
|
108
|
+
def interruptible_region
|
108
109
|
enter_interruptible_region
|
109
110
|
|
110
111
|
# XXX Note that there is a chance that we get the interrupt right after
|
111
112
|
# the readline call succeeded, but we'll never know, and we will retry the
|
112
113
|
# call, discarding that piece of input.
|
113
|
-
|
114
|
-
|
114
|
+
yield
|
115
115
|
rescue Interrupt
|
116
116
|
# We were asked to back off. The one requesting the interrupt will be
|
117
117
|
# waiting on the conditional for the interruptible flag to change to false.
|
@@ -122,7 +122,6 @@ class Pry
|
|
122
122
|
leave_interruptible_region
|
123
123
|
sleep 0.01
|
124
124
|
retry
|
125
|
-
|
126
125
|
ensure
|
127
126
|
leave_interruptible_region
|
128
127
|
end
|
data/lib/pry/inspector.rb
CHANGED
@@ -1,27 +1,39 @@
|
|
1
|
-
|
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
|
-
},
|
1
|
+
# frozen_string_literal: true
|
10
2
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
class Pry
|
4
|
+
class Inspector
|
5
|
+
MAP = {
|
6
|
+
"default" => {
|
7
|
+
value: Pry.config.print,
|
8
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip!)
|
9
|
+
The default Pry inspector. It has paging and color support, and uses
|
10
|
+
pretty_inspect when printing an object.
|
11
|
+
DESCRIPTION
|
12
|
+
},
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
"simple" => {
|
15
|
+
value: proc do |output, value|
|
16
|
+
begin
|
17
|
+
output.puts value.inspect
|
18
|
+
rescue RescuableException
|
19
|
+
output.puts "unknown"
|
20
|
+
end
|
21
|
+
end,
|
22
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
23
|
+
A simple inspector that uses #puts and #inspect when printing an
|
24
|
+
object. It has no pager, color, or pretty_inspect support.
|
25
|
+
DESCRIPTION
|
26
|
+
},
|
27
|
+
|
28
|
+
"clipped" => {
|
29
|
+
value: proc do |output, value|
|
30
|
+
output.puts Pry.view_clip(value, id: true)
|
31
|
+
end,
|
32
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
33
|
+
The clipped inspector has the same features as the 'simple' inspector
|
34
|
+
but prints large objects as a smaller string.
|
35
|
+
DESCRIPTION
|
36
|
+
}
|
37
|
+
}.freeze
|
38
|
+
end
|
27
39
|
end
|
data/lib/pry/last_exception.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# {Pry::LastException} is a proxy class who wraps an Exception object for
|
3
5
|
# {Pry#last_exception}. it extends the exception object with methods that
|
@@ -6,56 +8,54 @@
|
|
6
8
|
# the original exception object is not modified and method calls are forwarded
|
7
9
|
# to the wrapped exception object.
|
8
10
|
#
|
9
|
-
class Pry
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
11
|
+
class Pry
|
12
|
+
class LastException < BasicObject
|
13
|
+
attr_accessor :bt_index
|
14
|
+
|
15
|
+
def initialize(exception)
|
16
|
+
@exception = exception
|
17
|
+
@bt_index = 0
|
18
|
+
@file, @line = bt_source_location_for(0)
|
23
19
|
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def respond_to_missing?(name, include_all = false)
|
27
|
-
@e.respond_to?(name, include_all)
|
28
|
-
end
|
29
20
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
21
|
+
def method_missing(name, *args, &block)
|
22
|
+
if @exception.respond_to?(name)
|
23
|
+
@exception.public_send(name, *args, &block)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
def line
|
43
|
-
@line
|
44
|
-
end
|
29
|
+
def respond_to_missing?(name, include_all = false)
|
30
|
+
@exception.respond_to?(name, include_all)
|
31
|
+
end
|
45
32
|
|
46
|
-
|
47
|
-
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
# returns the path to a file for the current backtrace. see {#bt_index}.
|
36
|
+
#
|
37
|
+
attr_reader :file
|
38
|
+
|
39
|
+
#
|
40
|
+
# @return [Fixnum]
|
41
|
+
# returns the line for the current backtrace. see {#bt_index}.
|
42
|
+
#
|
43
|
+
attr_reader :line
|
44
|
+
|
45
|
+
# @return [Exception]
|
46
|
+
# returns the wrapped exception
|
47
|
+
#
|
48
|
+
def wrapped_exception
|
49
|
+
@exception
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
def bt_source_location_for(index)
|
53
|
+
backtrace[index] =~ /(.*):(\d+)/
|
54
|
+
[::Regexp.last_match(1), ::Regexp.last_match(2).to_i]
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
def inc_bt_index
|
58
|
+
@bt_index = (@bt_index + 1) % backtrace.size
|
59
|
+
end
|
60
60
|
end
|
61
61
|
end
|
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
|
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.
|
42
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, instance: true)
|
63
|
+
from_str(name, target, instance: true) ||
|
60
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
|
@@ -119,7 +134,9 @@ class Pry
|
|
119
134
|
# @param [Binding] target The binding where the method is looked up.
|
120
135
|
# @return [Pry::Method, nil]
|
121
136
|
def from_class(klass, name, target = TOPLEVEL_BINDING)
|
122
|
-
new(lookup_method_via_binding(klass, name, :instance_method, target))
|
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
|
|
@@ -132,7 +149,9 @@ class Pry
|
|
132
149
|
# @param [Binding] target The binding where the method is looked up.
|
133
150
|
# @return [Pry::Method, nil]
|
134
151
|
def from_obj(obj, name, target = TOPLEVEL_BINDING)
|
135
|
-
new(lookup_method_via_binding(obj, name, :method, target))
|
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`
|
@@ -140,9 +159,14 @@ class Pry
|
|
140
159
|
# @param [Boolean] include_super Whether to include methods from ancestors.
|
141
160
|
# @return [Array[Pry::Method]]
|
142
161
|
def all_from_class(klass, include_super = true)
|
143
|
-
%w
|
144
|
-
safe_send(
|
145
|
-
|
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
171
|
end
|
148
172
|
end
|
@@ -161,24 +185,19 @@ class Pry
|
|
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
|
@@ -220,15 +245,17 @@ class Pry
|
|
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.
|
@@ -238,7 +265,9 @@ class Pry
|
|
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
|
@@ -342,15 +371,16 @@ class Pry
|
|
342
371
|
# @return [Symbol] The visibility of the method. May be `:public`,
|
343
372
|
# `:protected`, or `:private`.
|
344
373
|
def visibility
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
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
|
354
384
|
end
|
355
385
|
|
356
386
|
# @return [String] A representation of the method's signature, including its
|
@@ -385,7 +415,7 @@ class Pry
|
|
385
415
|
# @return [Pry::Method, nil] The wrapped method that is called when you
|
386
416
|
# use "super" in the body of this method.
|
387
417
|
def super(times = 1)
|
388
|
-
if
|
418
|
+
if @method.is_a?(UnboundMethod)
|
389
419
|
sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times)
|
390
420
|
else
|
391
421
|
sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times)
|
@@ -404,7 +434,7 @@ class Pry
|
|
404
434
|
|
405
435
|
# @return [Boolean] Was the method defined outside a source file?
|
406
436
|
def dynamically_defined?
|
407
|
-
!!(source_file
|
437
|
+
!!(source_file && source_file =~ /(\(.*\))|<.*>/)
|
408
438
|
end
|
409
439
|
|
410
440
|
# @return [Boolean] Whether the method is unbound.
|
@@ -450,30 +480,36 @@ class Pry
|
|
450
480
|
end
|
451
481
|
|
452
482
|
# @return [Boolean]
|
453
|
-
def ==(
|
454
|
-
if
|
455
|
-
|
456
|
-
|
457
|
-
@method == obj
|
458
|
-
end
|
483
|
+
def ==(other)
|
484
|
+
return other == @method if other.is_a?(Pry::Method)
|
485
|
+
|
486
|
+
@method == other
|
459
487
|
end
|
460
488
|
|
461
489
|
# @param [Class] klass
|
462
490
|
# @return [Boolean]
|
463
491
|
def is_a?(klass)
|
464
|
-
klass == Pry::Method
|
492
|
+
(klass == Pry::Method) || @method.is_a?(klass)
|
465
493
|
end
|
466
494
|
alias kind_of? is_a?
|
467
495
|
|
468
496
|
# @param [String, Symbol] method_name
|
469
497
|
# @return [Boolean]
|
470
498
|
def respond_to?(method_name, include_all = false)
|
471
|
-
super
|
499
|
+
super || @method.respond_to?(method_name, include_all)
|
472
500
|
end
|
473
501
|
|
474
502
|
# Delegate any unknown calls to the wrapped method.
|
475
503
|
def method_missing(method_name, *args, &block)
|
476
|
-
@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
|
477
513
|
end
|
478
514
|
|
479
515
|
def comment
|
@@ -485,12 +521,17 @@ class Pry
|
|
485
521
|
# @return [YARD::CodeObjects::MethodObject]
|
486
522
|
# @raise [CommandError] when the method can't be found or `pry-doc` isn't installed.
|
487
523
|
def pry_doc_info
|
488
|
-
if
|
489
|
-
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
|
+
)
|
490
530
|
else
|
491
531
|
fail_msg = "Cannot locate this method: #{name}."
|
492
532
|
if Helpers::Platform.mri?
|
493
|
-
fail_msg += " Invoke the 'gem-install pry-doc' Pry command to get
|
533
|
+
fail_msg += " Invoke the 'gem-install pry-doc' Pry command to get " \
|
534
|
+
"access to Ruby Core documentation.\n"
|
494
535
|
end
|
495
536
|
raise CommandError, fail_msg
|
496
537
|
end
|
@@ -499,16 +540,22 @@ class Pry
|
|
499
540
|
# @param [Class, Module] ancestors The ancestors to investigate
|
500
541
|
# @return [Method] The unwrapped super-method
|
501
542
|
def super_using_ancestors(ancestors, times = 1)
|
502
|
-
next_owner =
|
543
|
+
next_owner = owner
|
503
544
|
times.times do
|
504
545
|
i = ancestors.index(next_owner) + 1
|
505
|
-
while ancestors[i] &&
|
546
|
+
while ancestors[i] &&
|
547
|
+
!(ancestors[i].method_defined?(name) ||
|
548
|
+
ancestors[i].private_method_defined?(name))
|
506
549
|
i += 1
|
507
550
|
end
|
508
|
-
next_owner = ancestors[i]
|
551
|
+
(next_owner = ancestors[i]) || (return nil)
|
509
552
|
end
|
510
553
|
|
511
|
-
|
554
|
+
begin
|
555
|
+
safe_send(next_owner, :instance_method, name)
|
556
|
+
rescue StandardError
|
557
|
+
nil
|
558
|
+
end
|
512
559
|
end
|
513
560
|
|
514
561
|
# @param [String] first_ln The first line of a method definition.
|
@@ -516,7 +563,7 @@ class Pry
|
|
516
563
|
def method_name_from_first_line(first_ln)
|
517
564
|
return nil if first_ln.strip !~ /^def /
|
518
565
|
|
519
|
-
tokens =
|
566
|
+
tokens = SyntaxHighlighter.tokenize(first_ln)
|
520
567
|
tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
|
521
568
|
tokens.each_cons(2) do |t1, t2|
|
522
569
|
if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
|
@@ -529,9 +576,7 @@ class Pry
|
|
529
576
|
|
530
577
|
def c_source
|
531
578
|
info = pry_doc_info
|
532
|
-
if info
|
533
|
-
strip_comments_from_c_code(info.source)
|
534
|
-
end
|
579
|
+
strip_comments_from_c_code(info.source) if info && info.source
|
535
580
|
end
|
536
581
|
|
537
582
|
def ruby_source
|
@@ -539,12 +584,14 @@ class Pry
|
|
539
584
|
# hacked version of `source_location` for our input buffer for methods
|
540
585
|
# defined in `(pry)`.
|
541
586
|
file, line = *source_location
|
542
|
-
|
587
|
+
unless file
|
588
|
+
raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!"
|
589
|
+
end
|
543
590
|
|
544
591
|
begin
|
545
592
|
code = Pry::Code.from_file(file).expression_at(line)
|
546
593
|
rescue SyntaxError => e
|
547
|
-
raise MethodSource::SourceNotFoundError
|
594
|
+
raise MethodSource::SourceNotFoundError, e.message
|
548
595
|
end
|
549
596
|
strip_leading_whitespace(code)
|
550
597
|
end
|