Skip to content

Commit

Permalink
Dump ancestors' methods by ls command
Browse files Browse the repository at this point in the history
  • Loading branch information
pocke committed May 2, 2021
1 parent 109cbfc commit 73edff2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
28 changes: 26 additions & 2 deletions lib/irb/cmd/ls.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "reline"
require 'set'
require_relative "nop"
require_relative "../color"

Expand All @@ -16,13 +17,36 @@ def execute(*arg, grep: nil)
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)

o.dump("constants", obj.constants) if obj.respond_to?(:constants)
o.dump("#{klass}.methods", obj.singleton_methods(false))
o.dump("#{klass}#methods", klass.public_instance_methods(false))
dump_singleton_methods(o, klass, obj)
dump_instance_methods(o, klass)
o.dump("instance variables", obj.instance_variables)
o.dump("class variables", klass.class_variables)
o.dump("locals", locals)
end

def dump_singleton_methods(o, klass, obj)
maps = class_method_map(obj.singleton_class.ancestors.take_while { |c| c != klass })
maps.each do |mod, methods|
name = mod == obj.singleton_class ? "#{klass}.methods" : "#{mod}#methods"
o.dump(name, methods)
end
end

def dump_instance_methods(o, klass)
maps = class_method_map(klass.ancestors)
maps.each do |mod, methods|
o.dump("#{mod}#methods", methods)
end
end

def class_method_map(classes)
dumped = Set.new
classes.reject { |mod| mod >= Object }.map do |mod|
methods = mod.public_instance_methods(false).select { |m| dumped.add?(m) }
[mod, methods]
end.reverse
end

class Output
MARGIN = " "

Expand Down
23 changes: 22 additions & 1 deletion test/irb/test_cmd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,24 @@ def test_irb_load

def test_ls
input = TestInputMethod.new([
"ls Object.new.tap { |o| o.instance_variable_set(:@a, 1) }\n",
"class C\n",
" def m1() end\n",
"end\n",

"module M\n",
" def m2() end\n",
"end\n",

"module M2\n",
" include M\n",
" def m3() end\n",
"end\n",

"obj = C.new\n",
"obj.instance_variable_set(:@a, 1)\n",
"obj.extend M2\n",
"def obj.m4() end\n",
"ls obj\n",
])
IRB.init_config(nil)
workspace = IRB::WorkSpace.new(self)
Expand All @@ -390,6 +407,10 @@ def test_ls
end
assert_empty err
assert_match(/^instance variables:\s+@a\n/m, out)
assert_match(/C#methods: m1\n/m, out)
assert_match(/M#methods: m2\n/m, out)
assert_match(/M2#methods: m3\n/m, out)
assert_match(/C.methods: m4\n/m, out)
end

def test_show_source
Expand Down

0 comments on commit 73edff2

Please sign in to comment.