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?
|
def command?
|
||||||
is_a?(Module) && self <= Pry::Command
|
is_a?(Module) && self <= Pry::Command
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
include Pry::Helpers::CommandHelpers
|
include Pry::Helpers::CommandHelpers
|
||||||
|
|
|
@ -22,7 +22,15 @@ class Pry
|
||||||
raise CommandError, no_definition_message if !code_object
|
raise CommandError, no_definition_message if !code_object
|
||||||
@original_code_object = 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
|
# show all monkey patches for a module
|
||||||
|
|
||||||
result = content_and_headers_for_all_module_candidates(code_object)
|
result = content_and_headers_for_all_module_candidates(code_object)
|
||||||
|
|
|
@ -603,6 +603,39 @@ describe "show-source" do
|
||||||
out.should_not =~ /def a; end/
|
out.should_not =~ /def a; end/
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue