pry 0.9.10pre1-i386-mingw32 → 0.9.11-i386-mingw32

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 (194) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG +63 -2
  3. data/CONTRIBUTORS +43 -25
  4. data/Gemfile +7 -0
  5. data/Guardfile +62 -0
  6. data/README.markdown +4 -4
  7. data/Rakefile +34 -35
  8. data/lib/pry.rb +107 -54
  9. data/lib/pry/cli.rb +34 -11
  10. data/lib/pry/code.rb +165 -182
  11. data/lib/pry/code/code_range.rb +70 -0
  12. data/lib/pry/code/loc.rb +92 -0
  13. data/lib/pry/code_object.rb +153 -0
  14. data/lib/pry/command.rb +160 -22
  15. data/lib/pry/command_set.rb +37 -26
  16. data/lib/pry/commands.rb +4 -27
  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 +53 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +78 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +84 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +30 -0
  26. data/lib/pry/commands/code_collector.rb +165 -0
  27. data/lib/pry/commands/deprecated_commands.rb +2 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/easter_eggs.rb +112 -0
  30. data/lib/pry/commands/edit.rb +206 -0
  31. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  32. data/lib/pry/commands/edit/file_and_line_locator.rb +38 -0
  33. data/lib/pry/commands/edit/method_patcher.rb +122 -0
  34. data/lib/pry/commands/exit.rb +42 -0
  35. data/lib/pry/commands/exit_all.rb +29 -0
  36. data/lib/pry/commands/exit_program.rb +24 -0
  37. data/lib/pry/commands/find_method.rb +199 -0
  38. data/lib/pry/commands/fix_indent.rb +19 -0
  39. data/lib/pry/commands/gem_cd.rb +26 -0
  40. data/lib/pry/commands/gem_install.rb +29 -0
  41. data/lib/pry/commands/gem_list.rb +33 -0
  42. data/lib/pry/commands/gem_open.rb +29 -0
  43. data/lib/pry/commands/gist.rb +95 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +161 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +51 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/ls.rb +339 -0
  50. data/lib/pry/commands/nesting.rb +25 -0
  51. data/lib/pry/commands/play.rb +69 -0
  52. data/lib/pry/commands/pry_backtrace.rb +26 -0
  53. data/lib/pry/commands/pry_version.rb +17 -0
  54. data/lib/pry/commands/raise_up.rb +32 -0
  55. data/lib/pry/commands/reload_code.rb +39 -0
  56. data/lib/pry/commands/reset.rb +18 -0
  57. data/lib/pry/commands/ri.rb +56 -0
  58. data/lib/pry/commands/save_file.rb +61 -0
  59. data/lib/pry/commands/shell_command.rb +43 -0
  60. data/lib/pry/commands/shell_mode.rb +27 -0
  61. data/lib/pry/commands/show_doc.rb +78 -0
  62. data/lib/pry/commands/show_info.rb +139 -0
  63. data/lib/pry/commands/show_input.rb +17 -0
  64. data/lib/pry/commands/show_source.rb +37 -0
  65. data/lib/pry/commands/simple_prompt.rb +22 -0
  66. data/lib/pry/commands/stat.rb +40 -0
  67. data/lib/pry/commands/switch_to.rb +23 -0
  68. data/lib/pry/commands/toggle_color.rb +20 -0
  69. data/lib/pry/commands/whereami.rb +114 -0
  70. data/lib/pry/commands/wtf.rb +57 -0
  71. data/lib/pry/completion.rb +120 -46
  72. data/lib/pry/config.rb +11 -0
  73. data/lib/pry/core_extensions.rb +30 -19
  74. data/lib/pry/editor.rb +129 -0
  75. data/lib/pry/helpers.rb +1 -0
  76. data/lib/pry/helpers/base_helpers.rb +89 -119
  77. data/lib/pry/helpers/command_helpers.rb +7 -122
  78. data/lib/pry/helpers/table.rb +100 -0
  79. data/lib/pry/helpers/text.rb +4 -4
  80. data/lib/pry/history_array.rb +5 -0
  81. data/lib/pry/hooks.rb +1 -3
  82. data/lib/pry/indent.rb +104 -30
  83. data/lib/pry/method.rb +66 -22
  84. data/lib/pry/module_candidate.rb +26 -15
  85. data/lib/pry/pager.rb +70 -0
  86. data/lib/pry/plugins.rb +1 -2
  87. data/lib/pry/pry_class.rb +63 -22
  88. data/lib/pry/pry_instance.rb +58 -37
  89. data/lib/pry/rubygem.rb +74 -0
  90. data/lib/pry/terminal_info.rb +43 -0
  91. data/lib/pry/test/helper.rb +185 -0
  92. data/lib/pry/version.rb +1 -1
  93. data/lib/pry/wrapped_module.rb +58 -24
  94. data/pry.gemspec +21 -37
  95. data/{test/test_cli.rb → spec/cli_spec.rb} +0 -0
  96. data/spec/code_object_spec.rb +277 -0
  97. data/{test/test_code.rb → spec/code_spec.rb} +19 -1
  98. data/{test/test_command_helpers.rb → spec/command_helpers_spec.rb} +0 -0
  99. data/{test/test_command_integration.rb → spec/command_integration_spec.rb} +38 -46
  100. data/{test/test_command_set.rb → spec/command_set_spec.rb} +18 -1
  101. data/{test/test_command.rb → spec/command_spec.rb} +250 -149
  102. data/spec/commands/amend_line_spec.rb +247 -0
  103. data/spec/commands/bang_spec.rb +19 -0
  104. data/spec/commands/cat_spec.rb +164 -0
  105. data/spec/commands/cd_spec.rb +250 -0
  106. data/spec/commands/disable_pry_spec.rb +25 -0
  107. data/spec/commands/edit_spec.rb +727 -0
  108. data/spec/commands/exit_all_spec.rb +34 -0
  109. data/spec/commands/exit_program_spec.rb +19 -0
  110. data/spec/commands/exit_spec.rb +34 -0
  111. data/{test/test_default_commands/test_find_method.rb → spec/commands/find_method_spec.rb} +27 -7
  112. data/spec/commands/gem_list_spec.rb +26 -0
  113. data/spec/commands/gist_spec.rb +75 -0
  114. data/{test/test_default_commands/test_help.rb → spec/commands/help_spec.rb} +8 -9
  115. data/spec/commands/hist_spec.rb +181 -0
  116. data/spec/commands/jump_to_spec.rb +15 -0
  117. data/spec/commands/ls_spec.rb +177 -0
  118. data/spec/commands/play_spec.rb +140 -0
  119. data/spec/commands/raise_up_spec.rb +56 -0
  120. data/spec/commands/save_file_spec.rb +177 -0
  121. data/spec/commands/show_doc_spec.rb +378 -0
  122. data/spec/commands/show_input_spec.rb +17 -0
  123. data/spec/commands/show_source_spec.rb +597 -0
  124. data/spec/commands/whereami_spec.rb +154 -0
  125. data/spec/completion_spec.rb +233 -0
  126. data/spec/control_d_handler_spec.rb +58 -0
  127. data/spec/editor_spec.rb +79 -0
  128. data/{test/test_exception_whitelist.rb → spec/exception_whitelist_spec.rb} +0 -0
  129. data/{test → spec/fixtures}/candidate_helper1.rb +0 -0
  130. data/{test → spec/fixtures}/candidate_helper2.rb +0 -0
  131. data/{test/test_default_commands → spec/fixtures}/example.erb +0 -0
  132. data/spec/fixtures/example_nesting.rb +33 -0
  133. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  134. data/{test → spec/fixtures}/testrc +0 -0
  135. data/{test → spec/fixtures}/testrcbad +0 -0
  136. data/spec/helper.rb +34 -0
  137. data/spec/helpers/bacon.rb +86 -0
  138. data/spec/helpers/mock_pry.rb +43 -0
  139. data/spec/helpers/table_spec.rb +83 -0
  140. data/{test/test_history_array.rb → spec/history_array_spec.rb} +21 -19
  141. data/{test/test_hooks.rb → spec/hooks_spec.rb} +0 -0
  142. data/{test/test_indent.rb → spec/indent_spec.rb} +24 -0
  143. data/{test/test_input_stack.rb → spec/input_stack_spec.rb} +4 -0
  144. data/{test/test_method.rb → spec/method_spec.rb} +65 -1
  145. data/{test/test_prompt.rb → spec/prompt_spec.rb} +0 -0
  146. data/{test/test_pry_defaults.rb → spec/pry_defaults_spec.rb} +14 -14
  147. data/{test/test_pry_history.rb → spec/pry_history_spec.rb} +15 -0
  148. data/spec/pry_output_spec.rb +95 -0
  149. data/{test/test_pry.rb → spec/pry_spec.rb} +74 -32
  150. data/{test/test_sticky_locals.rb → spec/sticky_locals_spec.rb} +27 -25
  151. data/{test/test_syntax_checking.rb → spec/syntax_checking_spec.rb} +17 -1
  152. data/{test/test_wrapped_module.rb → spec/wrapped_module_spec.rb} +92 -5
  153. metadata +239 -115
  154. data/examples/example_basic.rb +0 -15
  155. data/examples/example_command_override.rb +0 -32
  156. data/examples/example_commands.rb +0 -36
  157. data/examples/example_hooks.rb +0 -9
  158. data/examples/example_image_edit.rb +0 -67
  159. data/examples/example_input.rb +0 -7
  160. data/examples/example_input2.rb +0 -29
  161. data/examples/example_output.rb +0 -11
  162. data/examples/example_print.rb +0 -6
  163. data/examples/example_prompt.rb +0 -9
  164. data/examples/helper.rb +0 -6
  165. data/lib/pry/default_commands/cd.rb +0 -81
  166. data/lib/pry/default_commands/commands.rb +0 -62
  167. data/lib/pry/default_commands/context.rb +0 -98
  168. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  169. data/lib/pry/default_commands/editing.rb +0 -420
  170. data/lib/pry/default_commands/find_method.rb +0 -169
  171. data/lib/pry/default_commands/gems.rb +0 -84
  172. data/lib/pry/default_commands/gist.rb +0 -187
  173. data/lib/pry/default_commands/help.rb +0 -127
  174. data/lib/pry/default_commands/hist.rb +0 -120
  175. data/lib/pry/default_commands/input_and_output.rb +0 -306
  176. data/lib/pry/default_commands/introspection.rb +0 -410
  177. data/lib/pry/default_commands/ls.rb +0 -272
  178. data/lib/pry/default_commands/misc.rb +0 -38
  179. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  180. data/lib/pry/default_commands/whereami.rb +0 -92
  181. data/lib/pry/extended_commands/experimental.rb +0 -7
  182. data/test/helper.rb +0 -223
  183. data/test/test_completion.rb +0 -62
  184. data/test/test_control_d_handler.rb +0 -45
  185. data/test/test_default_commands/test_cd.rb +0 -321
  186. data/test/test_default_commands/test_context.rb +0 -288
  187. data/test/test_default_commands/test_documentation.rb +0 -315
  188. data/test/test_default_commands/test_gems.rb +0 -18
  189. data/test/test_default_commands/test_input.rb +0 -428
  190. data/test/test_default_commands/test_introspection.rb +0 -511
  191. data/test/test_default_commands/test_ls.rb +0 -151
  192. data/test/test_default_commands/test_shell.rb +0 -343
  193. data/test/test_default_commands/test_show_source.rb +0 -432
  194. data/test/test_pry_output.rb +0 -41
@@ -33,7 +33,7 @@ class Pry
33
33
  #
34
34
  # @param [String, #to_s] text
35
35
  # @return [String] _text_ stripped of any color codes.
36
- def strip_color text
36
+ def strip_color(text)
37
37
  text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
38
38
  end
39
39
 
@@ -42,7 +42,7 @@ class Pry
42
42
  #
43
43
  # @param [String, #to_s] text
44
44
  # @return [String] _text_
45
- def bold text
45
+ def bold(text)
46
46
  Pry.color ? "\e[1m#{text}\e[0m" : text.to_s
47
47
  end
48
48
 
@@ -59,7 +59,7 @@ class Pry
59
59
  # Executes the block with `Pry.color` set to false.
60
60
  # @yield
61
61
  # @return [void]
62
- def no_color &block
62
+ def no_color(&block)
63
63
  boolean = Pry.config.color
64
64
  Pry.config.color = false
65
65
  yield
@@ -70,7 +70,7 @@ class Pry
70
70
  # Executes the block with `Pry.config.pager` set to false.
71
71
  # @yield
72
72
  # @return [void]
73
- def no_pager &block
73
+ def no_pager(&block)
74
74
  boolean = Pry.config.pager
75
75
  Pry.config.pager = false
76
76
  yield
@@ -89,6 +89,11 @@ class Pry
89
89
  ((@count - size)...@count).map { |n| @hash[n] }
90
90
  end
91
91
 
92
+ def pop!
93
+ @hash.delete @count - 1
94
+ @count -= 1
95
+ end
96
+
92
97
  def inspect
93
98
  "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>"
94
99
  end
@@ -244,9 +244,7 @@ class Pry
244
244
  # @param [Symbol] hook_name Name of the hook.
245
245
  # @return [Boolean] Whether the hook by the name `hook_name`
246
246
  def hook_exists?(event_name, hook_name)
247
- !!@hooks[event_name].find { |name, _| name == hook_name }
247
+ !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name })
248
248
  end
249
- private :hook_exists?
250
-
251
249
  end
252
250
  end
@@ -17,9 +17,12 @@ class Pry
17
17
  class Indent
18
18
  include Helpers::BaseHelpers
19
19
 
20
+ # Raised if {#module_nesting} would not work.
21
+ class UnparseableNestingError < StandardError; end
22
+
20
23
  # @return [String] String containing the spaces to be inserted before the next line.
21
24
  attr_reader :indent_level
22
-
25
+
23
26
  # @return [Array<String>] The stack of open tokens.
24
27
  attr_reader :stack
25
28
 
@@ -51,6 +54,9 @@ class Pry
51
54
  # a single-line.
52
55
  SINGLELINE_TOKENS = %w(if while until unless rescue)
53
56
 
57
+ # Which tokens can be followed by an optional "do" keyword.
58
+ OPTIONAL_DO_TOKENS = %w(for while until)
59
+
54
60
  # Collection of token types that should be ignored. Without this list
55
61
  # keywords such as "class" inside strings would cause the code to be
56
62
  # indented incorrectly.
@@ -73,6 +79,32 @@ class Pry
73
79
  # don't affect the surrounding code.
74
80
  MIDWAY_TOKENS = %w(when else elsif ensure rescue)
75
81
 
82
+ # Clean the indentation of a fragment of ruby.
83
+ #
84
+ # @param [String] str
85
+ # @return [String]
86
+ def self.indent(str)
87
+ new.indent(str)
88
+ end
89
+
90
+ # Get the module nesting at the given point in the given string.
91
+ #
92
+ # NOTE If the line specified contains a method definition, then the nesting
93
+ # at the start of the method definition is used. Otherwise the nesting from
94
+ # the end of the line is used.
95
+ #
96
+ # @param [String] str The ruby code to analyze
97
+ # @param [Fixnum] line_number The line number (starting from 1)
98
+ # @return [Array<String>]
99
+ def self.nesting_at(str, line_number)
100
+ indent = new
101
+ lines = str.split("\n")
102
+ n = line_number - 1
103
+ to_indent = lines[0...n] + (lines[n] || "").split("def").first(1)
104
+ indent.indent(to_indent.join("\n") + "\n")
105
+ indent.module_nesting
106
+ end
107
+
76
108
  def initialize
77
109
  reset
78
110
  end
@@ -84,6 +116,8 @@ class Pry
84
116
  @heredoc_queue = []
85
117
  @close_heredocs = {}
86
118
  @string_start = nil
119
+ @awaiting_class = false
120
+ @module_nesting = []
87
121
  self
88
122
  end
89
123
 
@@ -129,7 +163,6 @@ class Pry
129
163
  new_prefix = prefix + SPACES * after
130
164
 
131
165
  line = prefix + line.lstrip unless previously_in_string
132
- line = line.rstrip + "\n" unless in_string?
133
166
 
134
167
  output += line
135
168
 
@@ -138,7 +171,7 @@ class Pry
138
171
 
139
172
  @indent_level = prefix
140
173
 
141
- return output.gsub(/\s+$/, '')
174
+ return output
142
175
  end
143
176
 
144
177
  # Get the indentation for the start of the next line.
@@ -192,7 +225,9 @@ class Pry
192
225
  last_token, last_kind = token, kind unless kind == :space
193
226
  next if IGNORE_TOKENS.include?(kind)
194
227
 
195
- seen_for_at << add_after if token == "for"
228
+ track_module_nesting(token, kind)
229
+
230
+ seen_for_at << add_after if OPTIONAL_DO_TOKENS.include?(token)
196
231
 
197
232
  if kind == :delimiter
198
233
  track_delimiter(token)
@@ -200,7 +235,8 @@ class Pry
200
235
  @stack << token
201
236
  add_after += 1
202
237
  elsif token == OPEN_TOKENS[@stack.last]
203
- @stack.pop
238
+ popped = @stack.pop
239
+ track_module_nesting_end(popped)
204
240
  if add_after == 0
205
241
  remove_before += 1
206
242
  else
@@ -282,6 +318,68 @@ class Pry
282
318
  "puts #{open_delimiters.join(", ")}"
283
319
  end
284
320
 
321
+ # Update the internal state relating to module nesting.
322
+ #
323
+ # It's responsible for adding to the @module_nesting array, which looks
324
+ # something like:
325
+ #
326
+ # [ ["class", "Foo"], ["module", "Bar::Baz"], ["class <<", "self"] ]
327
+ #
328
+ # A nil value in the @module_nesting array happens in two places: either
329
+ # when @awaiting_token is true and we're still waiting for the string to
330
+ # fill that space, or when a parse was rejected.
331
+ #
332
+ # At the moment this function is quite restricted about what formats it will
333
+ # parse, for example we disallow expressions after the class keyword. This
334
+ # could maybe be improved in the future.
335
+ #
336
+ # @param [String] token a token from Coderay
337
+ # @param [Symbol] kind the kind of that token
338
+ def track_module_nesting(token, kind)
339
+ if kind == :keyword && (token == "class" || token == "module")
340
+ @module_nesting << [token, nil]
341
+ @awaiting_class = true
342
+ elsif @awaiting_class
343
+ if kind == :operator && token == "<<" && @module_nesting.last[0] == "class"
344
+ @module_nesting.last[0] = "class <<"
345
+ @awaiting_class = true
346
+ elsif kind == :class && token =~ /\A(self|[A-Z:][A-Za-z0-9_:]*)\z/
347
+ @module_nesting.last[1] = token if kind == :class
348
+ @awaiting_class = false
349
+ else
350
+ # leave @nesting[-1][
351
+ @awaiting_class = false
352
+ end
353
+ end
354
+ end
355
+
356
+ # Update the internal state relating to module nesting on 'end'.
357
+ #
358
+ # If the current 'end' pairs up with a class or a module then we should
359
+ # pop an array off of @module_nesting
360
+ #
361
+ # @param [String] token a token from Coderay
362
+ # @param [Symbol] kind the kind of that token
363
+ def track_module_nesting_end(token, kind=:keyword)
364
+ if kind == :keyword && (token == "class" || token == "module")
365
+ @module_nesting.pop
366
+ end
367
+ end
368
+
369
+ # Return a list of strings which can be used to re-construct the Module.nesting at
370
+ # the current point in the file.
371
+ #
372
+ # Returns nil if the syntax of the file was not recognizable.
373
+ #
374
+ # @return [Array<String>]
375
+ def module_nesting
376
+ @module_nesting.map do |(kind, token)|
377
+ raise UnparseableNestingError, @module_nesting.inspect if token.nil?
378
+
379
+ "#{kind} #{token}"
380
+ end
381
+ end
382
+
285
383
  # Return a string which, when printed, will rewrite the previous line with
286
384
  # the correct indentation. Mostly useful for fixing 'end'.
287
385
  #
@@ -294,7 +392,7 @@ class Pry
294
392
  full_line = prompt + code
295
393
  whitespace = ' ' * overhang
296
394
 
297
- _, cols = screen_size
395
+ _, cols = TerminalInfo.screen_size
298
396
 
299
397
  cols = cols.to_i
300
398
  lines = cols != 0 ? (full_line.length / cols + 1) : 1
@@ -309,29 +407,5 @@ class Pry
309
407
 
310
408
  "#{move_up}#{prompt}#{colorize_code(code)}#{whitespace}#{move_down}"
311
409
  end
312
-
313
- # Return a pair of [rows, columns] which gives the size of the window.
314
- #
315
- # If the window size cannot be determined, return nil.
316
- def screen_size
317
- [
318
- # io/console adds a winsize method to IO streams.
319
- $stdout.tty? && $stdout.respond_to?(:winsize) && $stdout.winsize,
320
-
321
- # Some readlines also provides get_screen_size.
322
- Readline.respond_to?(:get_screen_size) && Readline.get_screen_size,
323
-
324
- # Otherwise try to use the environment (this may be out of date due
325
- # to window resizing, but it's better than nothing).
326
- [ENV["ROWS"], ENV["COLUMNS"],
327
-
328
- # If the user is running within ansicon, then use the screen size
329
- # that it reports (same caveats apply as with ROWS and COLUMNS)
330
- ENV['ANSICON'] =~ /\((.*)x(.*)\)/ && [$2, $1]
331
- ]
332
- ].detect do |(_, cols)|
333
- cols.to_i > 0
334
- end
335
- end
336
410
  end
337
411
  end
@@ -17,8 +17,11 @@ class Pry
17
17
  # This class wraps the normal `Method` and `UnboundMethod` classes
18
18
  # to provide extra functionality useful to Pry.
19
19
  class Method
20
+ extend Helpers::BaseHelpers
21
+ include Helpers::BaseHelpers
20
22
  include RbxMethod if Helpers::BaseHelpers.rbx?
21
23
  include Helpers::DocumentationHelpers
24
+ include CodeObject::Helpers
22
25
 
23
26
  class << self
24
27
  # Given a string representing a method name and optionally a binding to
@@ -40,18 +43,21 @@ class Pry
40
43
  from_binding(target)
41
44
  elsif name.to_s =~ /(.+)\#(\S+)\Z/
42
45
  context, meth_name = $1, $2
43
- from_module(target.eval(context), meth_name)
44
- elsif name.to_s =~ /(.+)\.(\S+)\Z/
45
- context, meth_name = $1, $2
46
- from_obj(target.eval(context), meth_name)
46
+ from_module(target.eval(context), meth_name, target)
47
+ elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/
48
+ context, meth_name = $1, $3
49
+ from_obj(target.eval(context), meth_name, target)
47
50
  elsif options[:instance]
48
- from_module(target.eval("self"), name)
51
+ from_module(target.eval("self"), name, target)
49
52
  elsif options[:methods]
50
- from_obj(target.eval("self"), name)
53
+ from_obj(target.eval("self"), name, target)
51
54
  else
52
55
  from_str(name, target, :instance => true) or
53
56
  from_str(name, target, :methods => true)
54
57
  end
58
+
59
+ rescue Pry::RescuableException
60
+ nil
55
61
  end
56
62
 
57
63
  # Given a `Binding`, try to extract the `::Method` it originated from and
@@ -62,12 +68,16 @@ class Pry
62
68
  # @return [Pry::Method, nil]
63
69
  #
64
70
  def from_binding(b)
65
- meth_name = b.eval('__method__')
71
+ meth_name = b.eval('::Kernel.__method__')
66
72
  if [:__script__, nil].include?(meth_name)
67
73
  nil
68
74
  else
69
75
  method = begin
70
- new(b.eval("Object.instance_method(:method).bind(self).call(#{meth_name.to_s.inspect})"))
76
+ if Object === b.eval('self')
77
+ new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name))
78
+ else
79
+ new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)'))
80
+ end
71
81
  rescue NameError, NoMethodError
72
82
  Disowned.new(b.eval('self'), meth_name.to_s)
73
83
  end
@@ -106,15 +116,32 @@ class Pry
106
116
  end
107
117
  end
108
118
 
119
+ # In order to support 2.0 Refinements we need to look up methods
120
+ # inside the relevant Binding.
121
+ # @param [Object] obj The owner/receiver of the method.
122
+ # @param [Symbol] method_name The name of the method.
123
+ # @param [Symbol] method_type The type of method: :method or :instance_method
124
+ # @param [Binding] target The binding where the method is looked up.
125
+ # @return [Method, UnboundMethod] The 'refined' method object.
126
+ def lookup_method_via_binding(obj, method_name, method_type, target=TOPLEVEL_BINDING)
127
+ Pry.current[:obj] = obj
128
+ Pry.current[:name] = method_name
129
+ receiver = obj.is_a?(Module) ? "Module" : "Kernel"
130
+ target.eval("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])")
131
+ ensure
132
+ Pry.current[:obj] = Pry.current[:name] = nil
133
+ end
134
+
109
135
  # Given a `Class` or `Module` and the name of a method, try to
110
136
  # instantiate a `Pry::Method` containing the instance method of
111
137
  # that name. Return `nil` if no such method exists.
112
138
  #
113
139
  # @param [Class, Module] klass
114
140
  # @param [String] name
141
+ # @param [Binding] target The binding where the method is looked up.
115
142
  # @return [Pry::Method, nil]
116
- def from_class(klass, name)
117
- new(safe_send(klass, :instance_method, name)) rescue nil
143
+ def from_class(klass, name, target=TOPLEVEL_BINDING)
144
+ new(lookup_method_via_binding(klass, name, :instance_method, target)) rescue nil
118
145
  end
119
146
  alias from_module from_class
120
147
 
@@ -124,9 +151,10 @@ class Pry
124
151
  #
125
152
  # @param [Object] obj
126
153
  # @param [String] name
154
+ # @param [Binding] target The binding where the method is looked up.
127
155
  # @return [Pry::Method, nil]
128
- def from_obj(obj, name)
129
- new(safe_send(obj, :method, name)) rescue nil
156
+ def from_obj(obj, name, target=TOPLEVEL_BINDING)
157
+ new(lookup_method_via_binding(obj, name, :method, target)) rescue nil
130
158
  end
131
159
 
132
160
  # Get all of the instance methods of a `Class` or `Module`
@@ -183,15 +211,6 @@ class Pry
183
211
  end.flatten(1)
184
212
  end
185
213
 
186
- # Acts like send but ignores any methods defined below Object or Class in the
187
- # inheritance hierarchy.
188
- # This is required to introspect methods on objects like Net::HTTP::Get that
189
- # have overridden the `method` method.
190
- def safe_send(obj, method, *args, &block)
191
- (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block)
192
- end
193
- public :safe_send
194
-
195
214
  # Get the singleton classes of superclasses that could define methods on
196
215
  # the given class object, and any modules they include.
197
216
  # If a module is included at multiple points in the ancestry, only
@@ -229,6 +248,12 @@ class Pry
229
248
  @wrapped_owner ||= Pry::WrappedModule.new(owner)
230
249
  end
231
250
 
251
+ # Get underlying object wrapped by this Pry::Method instance
252
+ # @return [Method, UnboundMethod, Proc]
253
+ def wrapped
254
+ @method
255
+ end
256
+
232
257
  # Is the method undefined? (aka `Disowned`)
233
258
  # @return [Boolean] false
234
259
  def undefined?
@@ -403,6 +428,24 @@ class Pry
403
428
  source_file == Pry.eval_path
404
429
  end
405
430
 
431
+ # @return [Array<String>] All known aliases for the method.
432
+ # @note On Ruby 1.8 this method always returns an empty Array for methods
433
+ # implemented in C.
434
+ def aliases
435
+ owner = @method.owner
436
+ # Avoid using `to_sym` on {Method#name}, which returns a `String`, because
437
+ # it won't be garbage collected.
438
+ name = @method.name
439
+
440
+ alias_list = owner.instance_methods.combination(2).select do |pair|
441
+ pair.include?(name) &&
442
+ owner.instance_method(pair.first) == owner.instance_method(pair.last)
443
+ end.flatten
444
+ alias_list.delete(name)
445
+
446
+ alias_list.map(&:to_s)
447
+ end
448
+
406
449
  # @return [Boolean] Is the method definitely an alias?
407
450
  def alias?
408
451
  name != original_name
@@ -475,7 +518,8 @@ class Pry
475
518
  end
476
519
  next_owner = ancestors[i] or return nil
477
520
  end
478
- next_owner.instance_method(name) rescue nil
521
+
522
+ safe_send(next_owner, :instance_method, name) rescue nil
479
523
  end
480
524
 
481
525
  # @param [String] first_ln The first line of a method definition.
@@ -8,18 +8,21 @@ class Pry
8
8
  # It provides access to the source, documentation, line and file
9
9
  # for a monkeypatch (reopening) of a class/module.
10
10
  class Candidate
11
+ include Pry::Helpers::DocumentationHelpers
12
+ include Pry::CodeObject::Helpers
11
13
  extend Forwardable
12
14
 
13
15
  # @return [String] The file where the module definition is located.
14
16
  attr_reader :file
17
+ alias_method :source_file, :file
15
18
 
16
19
  # @return [Fixnum] The line where the module definition is located.
17
20
  attr_reader :line
21
+ alias_method :source_line, :line
18
22
 
19
23
  # Methods to delegate to associated `Pry::WrappedModule instance`.
20
24
  to_delegate = [:lines_for_file, :method_candidates, :name, :wrapped,
21
- :yard_docs?, :number_of_candidates, :process_doc,
22
- :strip_leading_whitespace]
25
+ :yard_docs?, :number_of_candidates]
23
26
 
24
27
  def_delegators :@wrapper, *to_delegate
25
28
  private(*to_delegate)
@@ -61,7 +64,7 @@ class Pry
61
64
  return @doc if @doc
62
65
  raise CommandError, "Could not locate doc for #{wrapped}!" if file.nil?
63
66
 
64
- @doc = process_doc(Pry::Code.from_file(file).comment_describing(line))
67
+ @doc = strip_leading_hash_and_whitespace_from_ruby_comments(Pry::Code.from_file(file).comment_describing(line))
65
68
  end
66
69
 
67
70
  # @return [Array, nil] A `[String, Fixnum]` pair representing the
@@ -70,27 +73,35 @@ class Pry
70
73
  def source_location
71
74
  return @source_location if @source_location
72
75
 
73
- mod_type_string = wrapped.class.to_s.downcase
74
76
  file, line = first_method_source_location
75
-
76
77
  return nil if !file.is_a?(String)
77
78
 
78
- class_regexes = [/^\s*#{mod_type_string}\s*(\w*)(::)?#{wrapped.name.split(/::/).last}/,
79
- /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/,
80
- /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/]
81
-
82
- host_file_lines = lines_for_file(file)
83
-
84
- search_lines = host_file_lines[0..(line - 2)]
85
- idx = search_lines.rindex { |v| class_regexes.any? { |r| r =~ v } }
86
-
87
- @source_location = [file, idx + 1]
79
+ @source_location = [file, first_line_of_module_definition(file, line)]
88
80
  rescue Pry::RescuableException
89
81
  nil
90
82
  end
91
83
 
92
84
  private
93
85
 
86
+ # Locate the first line of the module definition.
87
+ # @param [String] file The file that contains the module
88
+ # definition (somewhere).
89
+ # @param [Fixnum] line The module definition should appear
90
+ # before this line (if it exists).
91
+ # @return [Fixnum] The line where the module is defined. This
92
+ # line number is one-indexed.
93
+ def first_line_of_module_definition(file, line)
94
+ searchable_lines = lines_for_file(file)[0..(line - 2)]
95
+ searchable_lines.rindex { |v| class_regexes.any? { |r| r =~ v } } + 1
96
+ end
97
+
98
+ def class_regexes
99
+ mod_type_string = wrapped.class.to_s.downcase
100
+ [/^\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped.name.split(/::/).last}/,
101
+ /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/,
102
+ /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/]
103
+ end
104
+
94
105
  # This method is used by `Candidate#source_location` as a
95
106
  # starting point for the search for the candidate's definition.
96
107
  # @return [Array] The source location of the base method used to