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.
Files changed (237) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1141 -0
  3. data/LICENSE +2 -2
  4. data/README.md +466 -0
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +97 -92
  10. data/lib/pry/code/code_file.rb +114 -0
  11. data/lib/pry/code/code_range.rb +7 -4
  12. data/lib/pry/code/loc.rb +27 -14
  13. data/lib/pry/code.rb +62 -90
  14. data/lib/pry/code_object.rb +83 -39
  15. data/lib/pry/color_printer.rb +66 -0
  16. data/lib/pry/command.rb +202 -371
  17. data/lib/pry/command_set.rb +151 -133
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -73
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -63
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +64 -47
  27. data/lib/pry/commands/cd.rb +42 -26
  28. data/lib/pry/commands/change_inspector.rb +34 -0
  29. data/lib/pry/commands/change_prompt.rb +51 -0
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +33 -24
  36. data/lib/pry/commands/edit.rb +183 -167
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -17
  40. data/lib/pry/commands/find_method.rb +167 -167
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +153 -132
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/lib/pry/commands/ls/constants.rb +75 -0
  48. data/lib/pry/commands/ls/formatter.rb +55 -0
  49. data/lib/pry/commands/ls/globals.rb +50 -0
  50. data/lib/pry/commands/ls/grep.rb +23 -0
  51. data/lib/pry/commands/ls/instance_vars.rb +40 -0
  52. data/lib/pry/commands/ls/interrogatable.rb +24 -0
  53. data/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  54. data/lib/pry/commands/ls/local_names.rb +37 -0
  55. data/lib/pry/commands/ls/local_vars.rb +47 -0
  56. data/lib/pry/commands/ls/ls_entity.rb +65 -0
  57. data/lib/pry/commands/ls/methods.rb +55 -0
  58. data/lib/pry/commands/ls/methods_helper.rb +50 -0
  59. data/lib/pry/commands/ls/self_methods.rb +34 -0
  60. data/lib/pry/commands/ls.rb +100 -303
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +93 -49
  63. data/lib/pry/commands/pry_backtrace.rb +22 -18
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +57 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -38
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +66 -34
  71. data/lib/pry/commands/shell_mode.rb +22 -20
  72. data/lib/pry/commands/show_doc.rb +80 -65
  73. data/lib/pry/commands/show_info.rb +193 -159
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +113 -33
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +21 -13
  79. data/lib/pry/commands/watch_expression/expression.rb +43 -0
  80. data/lib/pry/commands/watch_expression.rb +110 -0
  81. data/lib/pry/commands/whereami.rb +157 -134
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +290 -220
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +50 -27
  90. data/lib/pry/editor.rb +130 -102
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +73 -0
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +22 -151
  96. data/lib/pry/helpers/command_helpers.rb +55 -63
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -13
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -86
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +101 -70
  104. data/lib/pry/hooks.rb +67 -137
  105. data/lib/pry/indent.rb +79 -73
  106. data/lib/pry/input_completer.rb +283 -0
  107. data/lib/pry/input_lock.rb +129 -0
  108. data/lib/pry/inspector.rb +39 -0
  109. data/lib/pry/last_exception.rb +61 -0
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +51 -42
  112. data/lib/pry/method/weird_method_locator.rb +80 -44
  113. data/lib/pry/method.rb +225 -176
  114. data/lib/pry/object_path.rb +91 -0
  115. data/lib/pry/output.rb +136 -0
  116. data/lib/pry/pager.rb +227 -68
  117. data/lib/pry/prompt.rb +214 -0
  118. data/lib/pry/pry_class.rb +216 -289
  119. data/lib/pry/pry_instance.rb +438 -500
  120. data/lib/pry/repl.rb +256 -0
  121. data/lib/pry/repl_file_loader.rb +34 -35
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +36 -43
  138. data/lib/pry/wrapped_module.rb +102 -103
  139. data/lib/pry.rb +135 -261
  140. metadata +94 -283
  141. data/.document +0 -2
  142. data/.gitignore +0 -16
  143. data/.travis.yml +0 -21
  144. data/.yardopts +0 -1
  145. data/CHANGELOG +0 -534
  146. data/CONTRIBUTORS +0 -55
  147. data/Gemfile +0 -9
  148. data/Guardfile +0 -62
  149. data/README.markdown +0 -400
  150. data/Rakefile +0 -140
  151. data/TODO +0 -117
  152. data/lib/pry/commands/disabled_commands.rb +0 -2
  153. data/lib/pry/commands/gem_cd.rb +0 -26
  154. data/lib/pry/commands/gem_install.rb +0 -29
  155. data/lib/pry/commands/gem_list.rb +0 -33
  156. data/lib/pry/commands/gem_open.rb +0 -29
  157. data/lib/pry/commands/gist.rb +0 -102
  158. data/lib/pry/commands/install_command.rb +0 -51
  159. data/lib/pry/commands/simple_prompt.rb +0 -22
  160. data/lib/pry/commands.rb +0 -6
  161. data/lib/pry/completion.rb +0 -304
  162. data/lib/pry/custom_completions.rb +0 -6
  163. data/lib/pry/history_array.rb +0 -116
  164. data/lib/pry/plugins.rb +0 -103
  165. data/lib/pry/rbx_method.rb +0 -13
  166. data/lib/pry/rbx_path.rb +0 -22
  167. data/lib/pry/rubygem.rb +0 -74
  168. data/lib/pry/terminal.rb +0 -78
  169. data/lib/pry/test/helper.rb +0 -185
  170. data/man/pry.1 +0 -195
  171. data/man/pry.1.html +0 -204
  172. data/man/pry.1.ronn +0 -141
  173. data/pry.gemspec +0 -30
  174. data/spec/Procfile +0 -3
  175. data/spec/cli_spec.rb +0 -78
  176. data/spec/code_object_spec.rb +0 -277
  177. data/spec/code_spec.rb +0 -219
  178. data/spec/command_helpers_spec.rb +0 -29
  179. data/spec/command_integration_spec.rb +0 -644
  180. data/spec/command_set_spec.rb +0 -627
  181. data/spec/command_spec.rb +0 -821
  182. data/spec/commands/amend_line_spec.rb +0 -247
  183. data/spec/commands/bang_spec.rb +0 -19
  184. data/spec/commands/cat_spec.rb +0 -164
  185. data/spec/commands/cd_spec.rb +0 -250
  186. data/spec/commands/disable_pry_spec.rb +0 -25
  187. data/spec/commands/edit_spec.rb +0 -727
  188. data/spec/commands/exit_all_spec.rb +0 -34
  189. data/spec/commands/exit_program_spec.rb +0 -19
  190. data/spec/commands/exit_spec.rb +0 -34
  191. data/spec/commands/find_method_spec.rb +0 -70
  192. data/spec/commands/gem_list_spec.rb +0 -26
  193. data/spec/commands/gist_spec.rb +0 -79
  194. data/spec/commands/help_spec.rb +0 -56
  195. data/spec/commands/hist_spec.rb +0 -181
  196. data/spec/commands/jump_to_spec.rb +0 -15
  197. data/spec/commands/ls_spec.rb +0 -181
  198. data/spec/commands/play_spec.rb +0 -140
  199. data/spec/commands/raise_up_spec.rb +0 -56
  200. data/spec/commands/save_file_spec.rb +0 -177
  201. data/spec/commands/show_doc_spec.rb +0 -510
  202. data/spec/commands/show_input_spec.rb +0 -17
  203. data/spec/commands/show_source_spec.rb +0 -782
  204. data/spec/commands/whereami_spec.rb +0 -203
  205. data/spec/completion_spec.rb +0 -239
  206. data/spec/control_d_handler_spec.rb +0 -58
  207. data/spec/documentation_helper_spec.rb +0 -73
  208. data/spec/editor_spec.rb +0 -79
  209. data/spec/exception_whitelist_spec.rb +0 -21
  210. data/spec/fixtures/candidate_helper1.rb +0 -11
  211. data/spec/fixtures/candidate_helper2.rb +0 -8
  212. data/spec/fixtures/example.erb +0 -5
  213. data/spec/fixtures/example_nesting.rb +0 -33
  214. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  215. data/spec/fixtures/testrc +0 -2
  216. data/spec/fixtures/testrcbad +0 -2
  217. data/spec/fixtures/whereami_helper.rb +0 -6
  218. data/spec/helper.rb +0 -34
  219. data/spec/helpers/bacon.rb +0 -86
  220. data/spec/helpers/mock_pry.rb +0 -43
  221. data/spec/helpers/table_spec.rb +0 -105
  222. data/spec/history_array_spec.rb +0 -67
  223. data/spec/hooks_spec.rb +0 -522
  224. data/spec/indent_spec.rb +0 -301
  225. data/spec/input_stack_spec.rb +0 -90
  226. data/spec/method_spec.rb +0 -482
  227. data/spec/prompt_spec.rb +0 -60
  228. data/spec/pry_defaults_spec.rb +0 -419
  229. data/spec/pry_history_spec.rb +0 -99
  230. data/spec/pry_output_spec.rb +0 -95
  231. data/spec/pry_spec.rb +0 -504
  232. data/spec/run_command_spec.rb +0 -25
  233. data/spec/sticky_locals_spec.rb +0 -157
  234. data/spec/syntax_checking_spec.rb +0 -81
  235. data/spec/wrapped_module_spec.rb +0 -261
  236. data/wiki/Customizing-pry.md +0 -397
  237. data/wiki/Home.md +0 -4
data/lib/pry/method.rb CHANGED
@@ -1,5 +1,6 @@
1
- # -*- coding: utf-8 -*-
2
- require 'pry/helpers/documentation_helpers'
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 `Pry::Method`
32
- # instance.
30
+ # search in, find and return the requested method wrapped in a
31
+ # `Pry::Method` instance.
33
32
  #
34
- # @param [String, nil] name The name of the method to retrieve, or `nil` to
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 `name` doesn't
39
- # contain any context.
40
- # @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't
41
- # contain any context.
42
- # @return [Pry::Method, nil] A `Pry::Method` instance containing the requested
43
- # method, or `nil` if no method could be located matching the parameters.
44
- def from_str(name, target=TOPLEVEL_BINDING, options={})
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
- from_binding(target)
45
+ nil
47
46
  elsif name.to_s =~ /(.+)\#(\S+)\Z/
48
- context, meth_name = $1, $2
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, meth_name = $1, $3
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, :instance => true) or
59
- from_str(name, target, :methods => true)
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] b
74
+ # @param [Binding] binding
71
75
  # @return [Pry::Method, nil]
72
76
  #
73
- def from_binding(b)
74
- meth_name = b.eval('::Kernel.__method__')
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 = begin
79
- if Object === b.eval('self')
80
- new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name))
81
- else
82
- new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)'))
83
- end
84
- rescue NameError, NoMethodError
85
- Disowned.new(b.eval('self'), meth_name.to_s)
86
- end
87
-
88
- if WeirdMethodLocator.weird_method?(method, b)
89
- WeirdMethodLocator.new(method, b).get_method || method
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(obj, method_name, method_type, target=TOPLEVEL_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("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])")
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)) rescue nil
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)) rescue nil
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
- all_from_common(klass, :instance_method, include_super)
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
- # @param [Boolean] include_super Whether to include methods from ancestors.
178
+ #
179
+ # @param [Boolean] include_super
180
+ # indicates whether or not to include methods from ancestors.
181
+ #
148
182
  # @return [Array[Pry::Method]]
149
- def all_from_obj(obj, include_super=true)
150
- all_from_common(obj, :method, include_super)
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 = singleton_class(obj) rescue obj.class
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.ancestors).uniq
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
- /^define_singleton_method\(?\s*[:\"\']#{name}|^def\s*self\.#{name}/ =~ definition_line.strip
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
- /^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)
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
- resolution_order = klass.ancestors.map do |anc|
210
- [singleton_class(anc)] + singleton_class(anc).included_modules if anc.is_a?(Class)
211
- end.compact.flatten(1)
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 singleton_class(obj); class << obj; self; end end
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
- # A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`.
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 Method#name type.
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
- info = pry_doc_info
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
- # clone of MethodSource.source_helper that knows to use our
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 ||= case source_type
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
- if rbx? && !pry_method?
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 !rbx? and source_type == :c
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
- @visibility ||= if owner.public_instance_methods.any? { |m| m.to_s == name }
357
- :public
358
- elsif owner.protected_instance_methods.any? { |m| m.to_s == name }
359
- :protected
360
- elsif owner.private_instance_methods.any? { |m| m.to_s == name }
361
- :private
362
- else
363
- :none
364
- end
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 `&`. If the parameter names are unavailable,
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 |arr, (type, name)|
375
- name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
376
- arr << case type
377
- when :req then name.to_s
378
- when :opt then "#{name}=?"
379
- when :rest then "*#{name}"
380
- when :block then "&#{name}"
381
- else '?'
382
- end
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 UnboundMethod === @method
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 and 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
- alias_list = owner.instance_methods.combination(2).select do |pair|
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 ==(obj)
461
- if obj.is_a? Pry::Method
462
- obj == @method
463
- else
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 or @method.is_a?(klass)
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 or @method.respond_to?(method_name)
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.send(method_name, *args, &block)
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 Pry.config.has_pry_doc
492
- Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
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 mri_18? || mri_19?
496
- fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.'
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 = self.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] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name))
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] or return nil
552
+ (next_owner = ancestors[i]) || (return nil)
530
553
  end
531
554
 
532
- safe_send(next_owner, :instance_method, name) rescue nil
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 = CodeRay.scan(first_ln, :ruby)
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