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

Add support for BasicObjects to ls [Fixes #984]

This commit is contained in:
Conrad Irwin 2013-10-19 20:58:57 -07:00
parent 783e47bf9d
commit ac683892d1
3 changed files with 33 additions and 26 deletions

View file

@ -157,11 +157,7 @@ class Pry
def below_ceiling(obj) def below_ceiling(obj)
ceiling = if opts.present?(:quiet) ceiling = if opts.present?(:quiet)
[ [
if opts.present?(:'instance-methods') Pry::Method.safe_send(module_to_interrogate, :ancestors)[1]
Pry::Method.safe_send(obj, :ancestors)[1]
else
Pry::Method.safe_send(obj.class, :ancestors)[1]
end
] + Pry.config.ls.ceiling ] + Pry.config.ls.ceiling
elsif opts.present?(:verbose) elsif opts.present?(:verbose)
[] []
@ -178,6 +174,7 @@ class Pry
["-g does not make sense with a specified Object", :globals, !args.empty?], ["-g does not make sense with a specified Object", :globals, !args.empty?],
["-q does not make sense with -v", :quiet, opts.present?(:verbose)], ["-q does not make sense with -v", :quiet, opts.present?(:verbose)],
["-M only makes sense with a Module or a Class", :'instance-methods', !interrogating_a_module?], ["-M only makes sense with a Module or a Class", :'instance-methods', !interrogating_a_module?],
["-c only makes sense with a Module or a Class", :constants, !args.empty? && !interrogating_a_module?],
].each do |message, option, expression| ].each do |message, option, expression|
raise Pry::CommandError, message if opts.present?(option) && expression raise Pry::CommandError, message if opts.present?(option) && expression
end end
@ -187,6 +184,10 @@ class Pry
(Module === object_to_interrogate) (Module === object_to_interrogate)
end end
def module_to_interrogate
interrogating_a_module? ? object_to_interrogate : (class << object_to_interrogate; self.ancestors.first; end)
end
def write_out_globals def write_out_globals
return unless opts.present?(:globals) return unless opts.present?(:globals)
@ -196,9 +197,8 @@ class Pry
def write_out_constants def write_out_constants
return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?) return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?)
mod = interrogating_a_module? ? object_to_interrogate : object_to_interrogate.class constants = WrappedModule.new(module_to_interrogate).constants(opts.present?(:verbose))
constants = WrappedModule.new(mod).constants(opts.present?(:verbose)) output_section("constants", grep[format_constants(module_to_interrogate, constants)])
output_section("constants", grep[format_constants(mod, constants)])
end end
def write_out_methods def write_out_methods
@ -226,9 +226,12 @@ class Pry
def write_out_ivars def write_out_ivars
return unless opts.present?(:ivars) || !has_user_specified_any_options return unless opts.present?(:ivars) || !has_user_specified_any_options
klass = (interrogating_a_module? ? object_to_interrogate : object_to_interrogate.class) if Object === object_to_interrogate
ivars = Pry::Method.safe_send(object_to_interrogate, :instance_variables) ivars = Pry::Method.safe_send(object_to_interrogate, :instance_variables)
kvars = Pry::Method.safe_send(klass, :class_variables) else
ivars = [] #TODO: BasicObject support
end
kvars = Pry::Method.safe_send(module_to_interrogate, :class_variables)
output_section("instance variables", format_variables(:instance_var, ivars)) + output_section("instance variables", format_variables(:instance_var, ivars)) +
output_section("class variables", format_variables(:class_var, kvars)) output_section("class variables", format_variables(:class_var, kvars))
end end

View file

@ -139,7 +139,11 @@ class Pry
# @param [Boolean] include_super Whether to include methods from ancestors. # @param [Boolean] include_super Whether to include methods from ancestors.
# @return [Array[Pry::Method]] # @return [Array[Pry::Method]]
def all_from_class(klass, include_super=true) def all_from_class(klass, include_super=true)
all_from_common(klass, :instance_method, include_super) %w(public protected private).map do |visibility|
safe_send(klass, :"#{visibility}_instance_methods", include_super).map do |method_name|
new(safe_send(klass, :instance_method, method_name), :visibility => visibility.to_sym)
end
end.flatten(1)
end end
# Get all of the methods on an `Object` # Get all of the methods on an `Object`
@ -147,7 +151,7 @@ class Pry
# @param [Boolean] include_super Whether to include methods from ancestors. # @param [Boolean] include_super Whether to include methods from ancestors.
# @return [Array[Pry::Method]] # @return [Array[Pry::Method]]
def all_from_obj(obj, include_super=true) def all_from_obj(obj, include_super=true)
all_from_common(obj, :method, include_super) all_from_class(class << obj; self; end, include_super)
end end
# Get every `Class` and `Module`, in order, that will be checked when looking # Get every `Class` and `Module`, in order, that will be checked when looking
@ -188,19 +192,6 @@ class Pry
private private
# See all_from_class and all_from_obj.
# If method_type is :instance_method, obj must be a `Class` or a `Module`
# If method_type is :method, obj can be any `Object`
#
# N.B. we pre-cache the visibility here to avoid O(N²) behaviour in "ls".
def all_from_common(obj, method_type, include_super=true)
%w(public protected private).map do |visibility|
safe_send(obj, :"#{visibility}_#{method_type}s", include_super).map do |method_name|
new(safe_send(obj, method_type, method_name), :visibility => visibility.to_sym)
end
end.flatten(1)
end
# Get the singleton classes of superclasses that could define methods on # Get the singleton classes of superclasses that could define methods on
# the given class object, and any modules they include. # the given class object, and any modules they include.
# If a module is included at multiple points in the ancestry, only # If a module is included at multiple points in the ancestry, only

View file

@ -34,6 +34,19 @@ describe "ls" do
end end
end end
describe "BasicObject" do
it "should work on BasicObject" do
pry_eval("ls BasicObject.new").should =~ /BasicObject#methods:.*__id__.*__send__/
end
it "should work on subclasses of BasicObject" do
pry_eval(
"class LessBasic < BasicObject; def jaroussky; 5; end; end",
"ls LessBasic.new"
).should =~ /LessBasic#methods:.*jaroussky/
end
end
describe "methods" do describe "methods" do
it "should show public methods by default" do it "should show public methods by default" do
output = pry_eval("ls Class.new{ def goo; end; public :goo }.new") output = pry_eval("ls Class.new{ def goo; end; public :goo }.new")