From: timr Date: 2011-01-03T18:05:20+09:00 Subject: little tool for learning the ruby lookup path I have been looking at the process ruby utilizes for method lookup, and wrote the code below. It has proven very enlightening to me. I am sharing. It allows obj#method_table to be called where one normally uses obj#methods. It inserts markers (conspicuous method names) into the method array that delimit the source for the listed methods up to that point so that it is clear how the method array is composed. See the test case at the bottom for clarification. The most thrilling thing I have done this entire year is to monkey- patch methods and see them hop to the appropriate section of the method_table and disappear from the previous position. I'd be interested to hear any feedback interested rubyists have about the approach or if anyone has suggestions to refactor the code. Thanks, Tim module Kernel def method_table #for completness sake, include the self in inh_chain, that way we can see the singleton_methods if any exist inh_chain = self.class.ancestors.unshift(self) inh_chain.each do |anc| meth_name = anc.to_s.center(20,'_') #define bookmark method to mark the position of that portion of the lookup path if anc.respond_to? :class_eval begin anc.class_eval("def #{meth_name}; end" ) rescue end end if anc.respond_to?(:define_singleton_method) begin anc.define_singleton_method("singleton_to_left".to_s.center(25,'_').to_sym) {} #uncommnet the following line to see how subsequent singleton methods stack on #anc.define_singleton_method("Bsingleton".to_s.center(20,'').to_sym){} meth_name = "extension_to_right".to_s.center(25,'_').to_sym anc.extend(Module.new{eval("def #{meth_name};end")}) #uncommnet the following lines to see how subsequent extended methods stack on #meth_name = "extension".to_s.center(20,'→').to_sym #anc.extend(Module.new{eval "def B#{meth_name};end;def C#{meth_name};end"}) rescue end end end self.methods end end #######TEST CASE########### module First def added_in_first end end module Second def added_in_second end end class NewObject include First end no = NewObject.new no.extend(Second) def no.singleton_method end p no.method_table =>[:singleton_method, :____singleton_to_left____, :___extension_to_right____, :added_in_second, :_____NewObject______, :added_in_first, :_______First________, :_______Object_______, :nil?, :===, :=~, :! ~, :eql?, :class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :define_singleton_method, :hash, :__id__, :object_id, :to_enum, :enum_for, :gem, :method_table, :_______Kernel_______, :==, :equal?, :!, :! =, :instance_eval, :instance_exec, :__send__, :____BasicObject_____]