aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasataka Pocke Kuwabara <kuwabara@pocke.me>2021-05-02 17:50:46 +0900
committergit <svn-admin@ruby-lang.org>2021-05-08 14:00:40 +0900
commitde96ae9b717b51f8914f6f6916c3df0295364762 (patch)
treee52db188a21c6b509ae300e5220f7a54cf62aca5
parent30d2d72663adfbce80ee122a2f6763eff6a7674e (diff)
downloadruby-de96ae9b717b51f8914f6f6916c3df0295364762.tar.gz
[ruby/irb] Dump ancestors' methods by ls command
https://github.com/ruby/irb/commit/73edff287c
-rw-r--r--lib/irb/cmd/ls.rb28
-rw-r--r--test/irb/test_cmd.rb23
2 files changed, 48 insertions, 3 deletions
diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb
index f163f4f9e6..8a3c420f19 100644
--- a/lib/irb/cmd/ls.rb
+++ b/lib/irb/cmd/ls.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "reline"
+require 'set'
require_relative "nop"
require_relative "../color"
@@ -16,13 +17,36 @@ module IRB
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 = " "
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb
index 5b63e56800..1e537bdb85 100644
--- a/test/irb/test_cmd.rb
+++ b/test/irb/test_cmd.rb
@@ -377,7 +377,24 @@ module TestIRB
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)
@@ -390,6 +407,10 @@ module TestIRB
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