pry 0.10.0.pre2-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +25 -0
  4. data/README.md +406 -0
  5. data/bin/pry +16 -0
  6. data/lib/pry.rb +161 -0
  7. data/lib/pry/cli.rb +220 -0
  8. data/lib/pry/code.rb +346 -0
  9. data/lib/pry/code/code_file.rb +103 -0
  10. data/lib/pry/code/code_range.rb +71 -0
  11. data/lib/pry/code/loc.rb +92 -0
  12. data/lib/pry/code_object.rb +172 -0
  13. data/lib/pry/color_printer.rb +55 -0
  14. data/lib/pry/command.rb +692 -0
  15. data/lib/pry/command_set.rb +443 -0
  16. data/lib/pry/commands.rb +6 -0
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +62 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +41 -0
  26. data/lib/pry/commands/change_inspector.rb +27 -0
  27. data/lib/pry/commands/change_prompt.rb +26 -0
  28. data/lib/pry/commands/code_collector.rb +165 -0
  29. data/lib/pry/commands/disable_pry.rb +27 -0
  30. data/lib/pry/commands/disabled_commands.rb +2 -0
  31. data/lib/pry/commands/easter_eggs.rb +112 -0
  32. data/lib/pry/commands/edit.rb +195 -0
  33. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  34. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  35. data/lib/pry/commands/exit.rb +42 -0
  36. data/lib/pry/commands/exit_all.rb +29 -0
  37. data/lib/pry/commands/exit_program.rb +23 -0
  38. data/lib/pry/commands/find_method.rb +193 -0
  39. data/lib/pry/commands/fix_indent.rb +19 -0
  40. data/lib/pry/commands/gem_cd.rb +26 -0
  41. data/lib/pry/commands/gem_install.rb +32 -0
  42. data/lib/pry/commands/gem_list.rb +33 -0
  43. data/lib/pry/commands/gem_open.rb +29 -0
  44. data/lib/pry/commands/gist.rb +101 -0
  45. data/lib/pry/commands/help.rb +164 -0
  46. data/lib/pry/commands/hist.rb +180 -0
  47. data/lib/pry/commands/import_set.rb +22 -0
  48. data/lib/pry/commands/install_command.rb +53 -0
  49. data/lib/pry/commands/jump_to.rb +29 -0
  50. data/lib/pry/commands/list_inspectors.rb +35 -0
  51. data/lib/pry/commands/list_prompts.rb +35 -0
  52. data/lib/pry/commands/ls.rb +114 -0
  53. data/lib/pry/commands/ls/constants.rb +47 -0
  54. data/lib/pry/commands/ls/formatter.rb +49 -0
  55. data/lib/pry/commands/ls/globals.rb +48 -0
  56. data/lib/pry/commands/ls/grep.rb +21 -0
  57. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  58. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  59. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  60. data/lib/pry/commands/ls/local_names.rb +35 -0
  61. data/lib/pry/commands/ls/local_vars.rb +39 -0
  62. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  63. data/lib/pry/commands/ls/methods.rb +57 -0
  64. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  65. data/lib/pry/commands/ls/self_methods.rb +32 -0
  66. data/lib/pry/commands/nesting.rb +25 -0
  67. data/lib/pry/commands/play.rb +103 -0
  68. data/lib/pry/commands/pry_backtrace.rb +25 -0
  69. data/lib/pry/commands/pry_version.rb +17 -0
  70. data/lib/pry/commands/raise_up.rb +32 -0
  71. data/lib/pry/commands/reload_code.rb +62 -0
  72. data/lib/pry/commands/reset.rb +18 -0
  73. data/lib/pry/commands/ri.rb +60 -0
  74. data/lib/pry/commands/save_file.rb +61 -0
  75. data/lib/pry/commands/shell_command.rb +48 -0
  76. data/lib/pry/commands/shell_mode.rb +25 -0
  77. data/lib/pry/commands/show_doc.rb +83 -0
  78. data/lib/pry/commands/show_info.rb +195 -0
  79. data/lib/pry/commands/show_input.rb +17 -0
  80. data/lib/pry/commands/show_source.rb +50 -0
  81. data/lib/pry/commands/simple_prompt.rb +22 -0
  82. data/lib/pry/commands/stat.rb +40 -0
  83. data/lib/pry/commands/switch_to.rb +23 -0
  84. data/lib/pry/commands/toggle_color.rb +24 -0
  85. data/lib/pry/commands/watch_expression.rb +105 -0
  86. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  87. data/lib/pry/commands/whereami.rb +190 -0
  88. data/lib/pry/commands/wtf.rb +57 -0
  89. data/lib/pry/config.rb +24 -0
  90. data/lib/pry/config/behavior.rb +139 -0
  91. data/lib/pry/config/convenience.rb +26 -0
  92. data/lib/pry/config/default.rb +165 -0
  93. data/lib/pry/core_extensions.rb +131 -0
  94. data/lib/pry/editor.rb +133 -0
  95. data/lib/pry/exceptions.rb +77 -0
  96. data/lib/pry/helpers.rb +5 -0
  97. data/lib/pry/helpers/base_helpers.rb +113 -0
  98. data/lib/pry/helpers/command_helpers.rb +156 -0
  99. data/lib/pry/helpers/documentation_helpers.rb +75 -0
  100. data/lib/pry/helpers/options_helpers.rb +27 -0
  101. data/lib/pry/helpers/table.rb +109 -0
  102. data/lib/pry/helpers/text.rb +107 -0
  103. data/lib/pry/history.rb +125 -0
  104. data/lib/pry/history_array.rb +121 -0
  105. data/lib/pry/hooks.rb +230 -0
  106. data/lib/pry/indent.rb +406 -0
  107. data/lib/pry/input_completer.rb +242 -0
  108. data/lib/pry/input_lock.rb +132 -0
  109. data/lib/pry/inspector.rb +27 -0
  110. data/lib/pry/last_exception.rb +61 -0
  111. data/lib/pry/method.rb +546 -0
  112. data/lib/pry/method/disowned.rb +53 -0
  113. data/lib/pry/method/patcher.rb +125 -0
  114. data/lib/pry/method/weird_method_locator.rb +186 -0
  115. data/lib/pry/module_candidate.rb +136 -0
  116. data/lib/pry/object_path.rb +82 -0
  117. data/lib/pry/output.rb +50 -0
  118. data/lib/pry/pager.rb +234 -0
  119. data/lib/pry/plugins.rb +103 -0
  120. data/lib/pry/prompt.rb +26 -0
  121. data/lib/pry/pry_class.rb +375 -0
  122. data/lib/pry/pry_instance.rb +654 -0
  123. data/lib/pry/rbx_path.rb +22 -0
  124. data/lib/pry/repl.rb +202 -0
  125. data/lib/pry/repl_file_loader.rb +74 -0
  126. data/lib/pry/rubygem.rb +82 -0
  127. data/lib/pry/terminal.rb +79 -0
  128. data/lib/pry/test/helper.rb +170 -0
  129. data/lib/pry/version.rb +3 -0
  130. data/lib/pry/wrapped_module.rb +373 -0
  131. metadata +248 -0
data/lib/pry/method.rb ADDED
@@ -0,0 +1,546 @@
1
+ require 'pry/helpers/documentation_helpers'
2
+
3
+ class Pry
4
+ class << self
5
+ # If the given object is a `Pry::Method`, return it unaltered. If it's
6
+ # anything else, return it wrapped in a `Pry::Method` instance.
7
+ def Method(obj)
8
+ if obj.is_a? Pry::Method
9
+ obj
10
+ else
11
+ Pry::Method.new(obj)
12
+ end
13
+ end
14
+ end
15
+
16
+ # This class wraps the normal `Method` and `UnboundMethod` classes
17
+ # 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
+
23
+ extend Helpers::BaseHelpers
24
+ include Helpers::BaseHelpers
25
+ include Helpers::DocumentationHelpers
26
+ include CodeObject::Helpers
27
+
28
+ class << self
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 `Pry::Method`
31
+ # instance.
32
+ #
33
+ # @param [String] name The name of the method to retrieve.
34
+ # @param [Binding] target The context in which to search for the method.
35
+ # @param [Hash] options
36
+ # @option options [Boolean] :instance Look for an instance method if `name` doesn't
37
+ # contain any context.
38
+ # @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't
39
+ # contain any context.
40
+ # @return [Pry::Method, nil] A `Pry::Method` instance containing the requested
41
+ # method, or `nil` if name is `nil` or no method could be located matching the parameters.
42
+ def from_str(name, target=TOPLEVEL_BINDING, options={})
43
+ if name.nil?
44
+ nil
45
+ elsif name.to_s =~ /(.+)\#(\S+)\Z/
46
+ context, meth_name = $1, $2
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)
51
+ elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/
52
+ context, meth_name = $1, $3
53
+ from_obj(target.eval(context), meth_name, target)
54
+ elsif options[:instance]
55
+ from_module(target.eval("self"), name, target)
56
+ elsif options[:methods]
57
+ from_obj(target.eval("self"), name, target)
58
+ else
59
+ from_str(name, target, :instance => true) or
60
+ from_str(name, target, :methods => true)
61
+ end
62
+
63
+ rescue Pry::RescuableException
64
+ nil
65
+ end
66
+
67
+ # Given a `Binding`, try to extract the `::Method` it originated from and
68
+ # use it to instantiate a `Pry::Method`. Return `nil` if this isn't
69
+ # possible.
70
+ #
71
+ # @param [Binding] b
72
+ # @return [Pry::Method, nil]
73
+ #
74
+ def from_binding(b)
75
+ meth_name = b.eval('::Kernel.__method__')
76
+ if [:__script__, nil].include?(meth_name)
77
+ nil
78
+ else
79
+ method = begin
80
+ if Object === b.eval('self')
81
+ new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name))
82
+ else
83
+ new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)'))
84
+ end
85
+ rescue NameError, NoMethodError
86
+ Disowned.new(b.eval('self'), meth_name.to_s)
87
+ end
88
+
89
+ if WeirdMethodLocator.weird_method?(method, b)
90
+ WeirdMethodLocator.new(method, b).get_method || method
91
+ else
92
+ method
93
+ end
94
+ end
95
+ end
96
+
97
+ # In order to support 2.0 Refinements we need to look up methods
98
+ # inside the relevant Binding.
99
+ # @param [Object] obj The owner/receiver of the method.
100
+ # @param [Symbol] method_name The name of the method.
101
+ # @param [Symbol] method_type The type of method: :method or :instance_method
102
+ # @param [Binding] target The binding where the method is looked up.
103
+ # @return [Method, UnboundMethod] The 'refined' method object.
104
+ def lookup_method_via_binding(obj, method_name, method_type, target=TOPLEVEL_BINDING)
105
+ Pry.current[:obj] = obj
106
+ Pry.current[:name] = method_name
107
+ receiver = obj.is_a?(Module) ? "Module" : "Kernel"
108
+ target.eval("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])")
109
+ ensure
110
+ Pry.current[:obj] = Pry.current[:name] = nil
111
+ end
112
+
113
+ # Given a `Class` or `Module` and the name of a method, try to
114
+ # instantiate a `Pry::Method` containing the instance method of
115
+ # that name. Return `nil` if no such method exists.
116
+ #
117
+ # @param [Class, Module] klass
118
+ # @param [String] name
119
+ # @param [Binding] target The binding where the method is looked up.
120
+ # @return [Pry::Method, nil]
121
+ def from_class(klass, name, target=TOPLEVEL_BINDING)
122
+ new(lookup_method_via_binding(klass, name, :instance_method, target)) rescue nil
123
+ end
124
+ alias from_module from_class
125
+
126
+ # Given an object and the name of a method, try to instantiate
127
+ # a `Pry::Method` containing the method of that name bound to
128
+ # that object. Return `nil` if no such method exists.
129
+ #
130
+ # @param [Object] obj
131
+ # @param [String] name
132
+ # @param [Binding] target The binding where the method is looked up.
133
+ # @return [Pry::Method, nil]
134
+ def from_obj(obj, name, target=TOPLEVEL_BINDING)
135
+ new(lookup_method_via_binding(obj, name, :method, target)) rescue nil
136
+ end
137
+
138
+ # Get all of the instance methods of a `Class` or `Module`
139
+ # @param [Class,Module] klass
140
+ # @param [Boolean] include_super Whether to include methods from ancestors.
141
+ # @return [Array[Pry::Method]]
142
+ def all_from_class(klass, include_super=true)
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)
148
+ end
149
+
150
+ #
151
+ # Get all of the methods on an `Object`
152
+ #
153
+ # @param [Object] obj
154
+ #
155
+ # @param [Boolean] include_super
156
+ # indicates whether or not to include methods from ancestors.
157
+ #
158
+ # @return [Array[Pry::Method]]
159
+ #
160
+ def all_from_obj(obj, include_super=true)
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)
171
+ end
172
+
173
+ # Get every `Class` and `Module`, in order, that will be checked when looking
174
+ # for an instance method to call on this object.
175
+ # @param [Object] obj
176
+ # @return [Array[Class, Module]]
177
+ def resolution_order(obj)
178
+ if Class === obj
179
+ singleton_class_resolution_order(obj) + instance_resolution_order(Class)
180
+ else
181
+ klass = singleton_class_of(obj) rescue obj.class
182
+ instance_resolution_order(klass)
183
+ end
184
+ end
185
+
186
+ # Get every `Class` and `Module`, in order, that will be checked when looking
187
+ # for methods on instances of the given `Class` or `Module`.
188
+ # This does not treat singleton classes of classes specially.
189
+ # @param [Class, Module] klass
190
+ # @return [Array[Class, Module]]
191
+ def instance_resolution_order(klass)
192
+ # include klass in case it is a singleton class,
193
+ ([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq
194
+ end
195
+
196
+ def method_definition?(name, definition_line)
197
+ singleton_method_definition?(name, definition_line) ||
198
+ instance_method_definition?(name, definition_line)
199
+ end
200
+
201
+ def singleton_method_definition?(name, definition_line)
202
+ /^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*self\.#{Regexp.escape(name)}/ =~ definition_line.strip
203
+ end
204
+
205
+ def instance_method_definition?(name, definition_line)
206
+ /^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*#{Regexp.escape(name)}/ =~ definition_line.strip
207
+ end
208
+
209
+ # Get the singleton classes of superclasses that could define methods on
210
+ # the given class object, and any modules they include.
211
+ # If a module is included at multiple points in the ancestry, only
212
+ # the lowest copy will be returned.
213
+ def singleton_class_resolution_order(klass)
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)
218
+
219
+ resolution_order.reverse.uniq.reverse - Class.included_modules
220
+ end
221
+
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
229
+ end
230
+
231
+ # A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`.
232
+ #
233
+ # @param [::Method, UnboundMethod, Proc] method
234
+ # @param [Hash] known_info Can be used to pre-cache expensive to compute stuff.
235
+ # @return [Pry::Method]
236
+ def initialize(method, known_info={})
237
+ @method = method
238
+ @visibility = known_info[:visibility]
239
+ end
240
+
241
+ # Get the name of the method as a String, regardless of the underlying Method#name type.
242
+ # @return [String]
243
+ def name
244
+ @method.name.to_s
245
+ end
246
+
247
+ # Get the owner of the method as a Pry::Module
248
+ # @return [Pry::Module]
249
+ def wrapped_owner
250
+ @wrapped_owner ||= Pry::WrappedModule.new(owner)
251
+ end
252
+
253
+ # Get underlying object wrapped by this Pry::Method instance
254
+ # @return [Method, UnboundMethod, Proc]
255
+ def wrapped
256
+ @method
257
+ end
258
+
259
+ # Is the method undefined? (aka `Disowned`)
260
+ # @return [Boolean] false
261
+ def undefined?
262
+ false
263
+ end
264
+
265
+ # Get the name of the method including the class on which it was defined.
266
+ # @example
267
+ # method(:puts).method_name
268
+ # => "Kernel.puts"
269
+ # @return [String]
270
+ def name_with_owner
271
+ "#{wrapped_owner.method_prefix}#{name}"
272
+ end
273
+
274
+ # @return [String, nil] The source code of the method, or `nil` if it's unavailable.
275
+ def source
276
+ @source ||= case source_type
277
+ when :c
278
+ c_source
279
+ when :ruby
280
+ ruby_source
281
+ end
282
+ end
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
+
290
+ # Can we get the source code for this method?
291
+ # @return [Boolean]
292
+ def source?
293
+ !!source
294
+ rescue MethodSource::SourceNotFoundError
295
+ false
296
+ end
297
+
298
+ # @return [String, nil] The documentation for the method, or `nil` if it's
299
+ # unavailable.
300
+ def doc
301
+ @doc ||= case source_type
302
+ when :c
303
+ info = pry_doc_info
304
+ info.docstring if info
305
+ when :ruby
306
+ get_comment_content(comment)
307
+ end
308
+ end
309
+
310
+ # @return [Symbol] The source type of the method. The options are
311
+ # `:ruby` for Ruby methods or `:c` for methods written in C.
312
+ def source_type
313
+ source_location.nil? ? :c : :ruby
314
+ end
315
+
316
+ # @return [String, nil] The name of the file the method is defined in, or
317
+ # `nil` if the filename is unavailable.
318
+ def source_file
319
+ if source_location.nil?
320
+ if !rbx? and source_type == :c
321
+ info = pry_doc_info
322
+ info.file if info
323
+ end
324
+ else
325
+ source_location.first
326
+ end
327
+ end
328
+
329
+ # @return [Fixnum, nil] The line of code in `source_file` which begins
330
+ # the method's definition, or `nil` if that information is unavailable.
331
+ def source_line
332
+ source_location.nil? ? nil : source_location.last
333
+ end
334
+
335
+ # @return [Range, nil] The range of lines in `source_file` which contain
336
+ # the method's definition, or `nil` if that information is unavailable.
337
+ def source_range
338
+ source_location.nil? ? nil : (source_line)..(source_line + source.lines.count - 1)
339
+ end
340
+
341
+ # @return [Symbol] The visibility of the method. May be `:public`,
342
+ # `:protected`, or `:private`.
343
+ def visibility
344
+ @visibility ||= if owner.public_instance_methods.any? { |m| m.to_s == name }
345
+ :public
346
+ elsif owner.protected_instance_methods.any? { |m| m.to_s == name }
347
+ :protected
348
+ elsif owner.private_instance_methods.any? { |m| m.to_s == name }
349
+ :private
350
+ else
351
+ :none
352
+ end
353
+ end
354
+
355
+ # @return [String] A representation of the method's signature, including its
356
+ # name and parameters. Optional and "rest" parameters are marked with `*`
357
+ # and block parameters with `&`. If the parameter names are unavailable,
358
+ # they're given numbered names instead.
359
+ # Paraphrased from `awesome_print` gem.
360
+ def signature
361
+ if respond_to?(:parameters)
362
+ args = parameters.inject([]) do |arr, (type, name)|
363
+ name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
364
+ arr << case type
365
+ when :req then name.to_s
366
+ when :opt then "#{name}=?"
367
+ when :rest then "*#{name}"
368
+ when :block then "&#{name}"
369
+ else '?'
370
+ end
371
+ end
372
+ else
373
+ args = (1..arity.abs).map { |i| "arg#{i}" }
374
+ args[-1] = "*#{args[-1]}" if arity < 0
375
+ end
376
+
377
+ "#{name}(#{args.join(', ')})"
378
+ end
379
+
380
+ # @return [Pry::Method, nil] The wrapped method that is called when you
381
+ # use "super" in the body of this method.
382
+ def super(times=1)
383
+ if UnboundMethod === @method
384
+ sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times)
385
+ else
386
+ sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times)
387
+ sup &&= sup.bind(receiver)
388
+ end
389
+ Pry::Method.new(sup) if sup
390
+ end
391
+
392
+ # @return [String, nil] The original name the method was defined under,
393
+ # before any aliasing, or `nil` if it can't be determined.
394
+ def original_name
395
+ return nil if source_type != :ruby
396
+ method_name_from_first_line(source.lines.first)
397
+ end
398
+
399
+ # @return [Boolean] Was the method defined outside a source file?
400
+ def dynamically_defined?
401
+ !!(source_file and source_file =~ /(\(.*\))|<.*>/)
402
+ end
403
+
404
+ # @return [Boolean] Whether the method is unbound.
405
+ def unbound_method?
406
+ is_a?(::UnboundMethod)
407
+ end
408
+
409
+ # @return [Boolean] Whether the method is bound.
410
+ def bound_method?
411
+ is_a?(::Method)
412
+ end
413
+
414
+ # @return [Boolean] Whether the method is a singleton method.
415
+ def singleton_method?
416
+ wrapped_owner.singleton_class?
417
+ end
418
+
419
+ # @return [Boolean] Was the method defined within the Pry REPL?
420
+ def pry_method?
421
+ source_file == Pry.eval_path
422
+ end
423
+
424
+ # @return [Array<String>] All known aliases for the method.
425
+ def aliases
426
+ owner = @method.owner
427
+ # Avoid using `to_sym` on {Method#name}, which returns a `String`, because
428
+ # it won't be garbage collected.
429
+ name = @method.name
430
+
431
+ all_methods_to_compare = owner.instance_methods | owner.private_instance_methods
432
+ alias_list = all_methods_to_compare.combination(2).select do |pair|
433
+ pair.include?(name) &&
434
+ owner.instance_method(pair.first) == owner.instance_method(pair.last)
435
+ end.flatten
436
+ alias_list.delete(name)
437
+
438
+ alias_list.map(&:to_s)
439
+ end
440
+
441
+ # @return [Boolean] Is the method definitely an alias?
442
+ def alias?
443
+ name != original_name
444
+ end
445
+
446
+ # @return [Boolean]
447
+ def ==(obj)
448
+ if obj.is_a? Pry::Method
449
+ obj == @method
450
+ else
451
+ @method == obj
452
+ end
453
+ end
454
+
455
+ # @param [Class] klass
456
+ # @return [Boolean]
457
+ def is_a?(klass)
458
+ klass == Pry::Method or @method.is_a?(klass)
459
+ end
460
+ alias kind_of? is_a?
461
+
462
+ # @param [String, Symbol] method_name
463
+ # @return [Boolean]
464
+ def respond_to?(method_name)
465
+ super or @method.respond_to?(method_name)
466
+ end
467
+
468
+ # Delegate any unknown calls to the wrapped method.
469
+ def method_missing(method_name, *args, &block)
470
+ @method.send(method_name, *args, &block)
471
+ end
472
+
473
+ def comment
474
+ Pry::Code.from_file(source_file).comment_describing(source_line)
475
+ end
476
+
477
+ private
478
+
479
+ # @return [YARD::CodeObjects::MethodObject]
480
+ # @raise [CommandError] when the method can't be found or `pry-doc` isn't installed.
481
+ def pry_doc_info
482
+ if Pry.config.has_pry_doc
483
+ Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
484
+ else
485
+ fail_msg = "Cannot locate this method: #{name}."
486
+ if mri?
487
+ fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.'
488
+ end
489
+ raise CommandError, fail_msg
490
+ end
491
+ end
492
+
493
+ # @param [Class, Module] ancestors The ancestors to investigate
494
+ # @return [Method] The unwrapped super-method
495
+ def super_using_ancestors(ancestors, times=1)
496
+ next_owner = self.owner
497
+ times.times do
498
+ i = ancestors.index(next_owner) + 1
499
+ while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name))
500
+ i += 1
501
+ end
502
+ next_owner = ancestors[i] or return nil
503
+ end
504
+
505
+ safe_send(next_owner, :instance_method, name) rescue nil
506
+ end
507
+
508
+ # @param [String] first_ln The first line of a method definition.
509
+ # @return [String, nil]
510
+ def method_name_from_first_line(first_ln)
511
+ return nil if first_ln.strip !~ /^def /
512
+
513
+ tokens = CodeRay.scan(first_ln, :ruby)
514
+ tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
515
+ tokens.each_cons(2) do |t1, t2|
516
+ if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
517
+ return t2.first
518
+ end
519
+ end
520
+
521
+ nil
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
545
+ end
546
+ end