diff --git a/lib/irb/command/ls.rb b/lib/irb/command/ls.rb index 944efd757..eae643ff4 100644 --- a/lib/irb/command/ls.rb +++ b/lib/irb/command/ls.rb @@ -55,11 +55,13 @@ def execute(arg) o = Output.new(grep: grep) - klass = (obj.class == Class || obj.class == Module ? obj : obj.class) + klass = Kernel.instance_method(:class).bind(obj).call + obj_is_class_or_module = Module === obj + klass = obj_is_class_or_module ? obj : klass - o.dump("constants", obj.constants) if obj.respond_to?(:constants) + o.dump("constants", obj.constants) if obj_is_class_or_module dump_methods(o, klass, obj) - o.dump("instance variables", obj.instance_variables) + o.dump("instance variables", Kernel.instance_method(:instance_variables).bind(obj).call) o.dump("class variables", klass.class_variables) o.dump("locals", locals) if locals o.print_result @@ -67,7 +69,7 @@ def execute(arg) end def dump_methods(o, klass, obj) - singleton_class = begin obj.singleton_class; rescue TypeError; nil end + singleton_class = begin Kernel.instance_method(:singleton_class).bind(obj).call; rescue TypeError; nil end dumped_mods = Array.new ancestors = klass.ancestors ancestors = ancestors.reject { |c| c >= Object } if klass < Object diff --git a/test/irb/command/test_ls.rb b/test/irb/command/test_ls.rb new file mode 100644 index 000000000..d865fe576 --- /dev/null +++ b/test/irb/command/test_ls.rb @@ -0,0 +1,71 @@ +require "tempfile" +require_relative "../helper" + +module TestIRB + class LSTest < IntegrationTestCase + def setup + super + + write_ruby <<~'RUBY' + class Foo + class Bar + def bar + "this is bar" + end + end + + def foo + "this is foo" + end + end + + class BO < BasicObject + ONE = 1 + def baz + "this is baz" + end + end + + binding.irb + RUBY + end + + def test_ls_class + out = run_ruby_file do + type "ls Foo" + type "exit" + end + + assert_match(/constants: Bar/, out) + assert_match(/Foo#methods: foo/, out) + end + + def test_ls_instance + out = run_ruby_file do + type "ls Foo.new" + type "exit" + end + + assert_match(/Foo#methods: foo/, out) + end + + def test_ls_basic_object + out = run_ruby_file do + type "ls BO" + type "exit" + end + + assert_match(/constants:.*ONE/, out) + assert_match(/BO#methods: baz/, out) + end + + def test_ls_basic_object_instance + out = run_ruby_file do + type "ls BO.new" + type "exit" + end + + assert_match(/BO#methods: baz/, out) + end + end +end