ruby-changes:66101
From: Masataka <ko1@a...>
Date: Sat, 8 May 2021 14:00:58 +0900 (JST)
Subject: [ruby-changes:66101] de96ae9b71 (master): [ruby/irb] Dump ancestors' methods by ls command
https://git.ruby-lang.org/ruby.git/commit/?id=de96ae9b71 From de96ae9b717b51f8914f6f6916c3df0295364762 Mon Sep 17 00:00:00 2001 From: Masataka Pocke Kuwabara <kuwabara@p...> Date: Sun, 2 May 2021 17:50:46 +0900 Subject: [ruby/irb] Dump ancestors' methods by ls command https://github.com/ruby/irb/commit/73edff287c --- lib/irb/cmd/ls.rb | 28 ++++++++++++++++++++++++++-- test/irb/test_cmd.rb | 23 ++++++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/irb/cmd/ls.rb b/lib/irb/cmd/ls.rb index f163f4f..8a3c420 100644 --- a/lib/irb/cmd/ls.rb +++ b/lib/irb/cmd/ls.rb @@ -1,6 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/irb/cmd/ls.rb#L1 # frozen_string_literal: true require "reline" +require 'set' require_relative "nop" require_relative "../color" @@ -16,13 +17,36 @@ module IRB https://github.com/ruby/ruby/blob/trunk/lib/irb/cmd/ls.rb#L17 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 5b63e56..1e537bd 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -377,7 +377,24 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_cmd.rb#L377 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 https://github.com/ruby/ruby/blob/trunk/test/irb/test_cmd.rb#L407 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 -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/