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:
parent
6a690e162e
commit
f289862ac6
3 changed files with 64 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue