1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

show-source: if the current context is a C object, display a warning

Fixes #691 (some adjustments to show-source behaviour)
This commit is contained in:
Kyrylo Silin 2015-02-27 06:00:10 +02:00
parent 6a690e162e
commit f289862ac6
3 changed files with 64 additions and 1 deletions

View file

@ -37,6 +37,28 @@ class Pry
def command?
is_a?(Module) && self <= Pry::Command
end
# @return [Boolean] `true` if this module was defined by means of the C API,
# `false` if it's a Ruby module.
# @note If a module defined by C was extended with a lot of methods written
# in Ruby, this method would fail.
def c_module?
if is_a?(WrappedModule)
method_locations = wrapped.methods(false).map do |m|
wrapped.method(m).source_location
end
method_locations.concat(wrapped.instance_methods(false).map do |m|
wrapped.instance_method(m).source_location
end)
c_methods = method_locations.grep(nil).count
ruby_methods = method_locations.count - c_methods
c_methods > ruby_methods
end
end
end
include Pry::Helpers::CommandHelpers

View file

@ -22,7 +22,15 @@ class Pry
raise CommandError, no_definition_message if !code_object
@original_code_object = code_object
if show_all_modules?(code_object)
if !obj_name && code_object.c_module? && !opts[:all]
result = "Warning: You're inside an object, whose class is defined by means\n" +
" of the C Ruby API. Pry cannot display the information for\n" +
" this class."
if code_object.candidates.any?
result += "\n However, you can view monkey-patches applied to this class.\n" +
" Just execute the same command with the '--all' switch."
end
elsif show_all_modules?(code_object)
# show all monkey patches for a module
result = content_and_headers_for_all_module_candidates(code_object)

View file

@ -603,6 +603,39 @@ describe "show-source" do
out.should_not =~ /def a; end/
end
end
describe "monkey-patched C modules" do
# Monkey-patch Array and add 15 methods, so its internal rank is
# high enough to make this definition primary.
class Array
15.times do |i|
define_method(:"doge#{i}") do
:"doge#{i}"
end
end
end
describe "when current context is a C object" do
it "should display a warning, and not monkey-patched definition" do
out = pry_eval([1, 2, 3], 'show-source')
expect(out).not_to match(/doge/)
expect(out).to match(/warning/i)
end
it "recommends to use the --all switch when other candidates are found" do
out = pry_eval([], 'show-source')
expect(out).to match(/'--all' switch/i)
end
end
describe "when current context is something other than a C object" do
it "should display a candidate, not a warning" do
out = pry_eval('show-source Array')
expect(out).to match(/doge/)
expect(out).not_to match(/warning/i)
end
end
end
end
end
end