11# frozen_string_literal: true
22
33require "reline"
4+ require 'set'
45require_relative "nop"
56require_relative "../color"
67
@@ -16,13 +17,36 @@ def execute(*arg, grep: nil)
1617 klass = ( obj . class == Class || obj . class == Module ? obj : obj . class )
1718
1819 o . dump ( "constants" , obj . constants ) if obj . respond_to? ( :constants )
19- o . dump ( " #{ klass } .methods" , obj . singleton_methods ( false ) )
20- o . dump ( " #{ klass } #methods" , klass . public_instance_methods ( false ) )
20+ dump_singleton_methods ( o , klass , obj )
21+ dump_instance_methods ( o , klass )
2122 o . dump ( "instance variables" , obj . instance_variables )
2223 o . dump ( "class variables" , klass . class_variables )
2324 o . dump ( "locals" , locals )
2425 end
2526
27+ def dump_singleton_methods ( o , klass , obj )
28+ maps = class_method_map ( obj . singleton_class . ancestors . take_while { |c | c != klass } )
29+ maps . each do |mod , methods |
30+ name = mod == obj . singleton_class ? "#{ klass } .methods" : "#{ mod } #methods"
31+ o . dump ( name , methods )
32+ end
33+ end
34+
35+ def dump_instance_methods ( o , klass )
36+ maps = class_method_map ( klass . ancestors )
37+ maps . each do |mod , methods |
38+ o . dump ( "#{ mod } #methods" , methods )
39+ end
40+ end
41+
42+ def class_method_map ( classes )
43+ dumped = Set . new
44+ classes . reject { |mod | mod >= Object } . map do |mod |
45+ methods = mod . public_instance_methods ( false ) . select { |m | dumped . add? ( m ) }
46+ [ mod , methods ]
47+ end . reverse
48+ end
49+
2650 class Output
2751 MARGIN = " "
2852
0 commit comments