对象的Ruby方法查找路径

是否有内置的Ruby方法或知名的库来返回对象的整个方法查找链? Ruby查看一个令人困惑的类序列(如本问题中所讨论的),例如与消息对应的方法,如果没有类响应消息,则调用接收器上的method_missing

我把以下代码放在一起,但我确定它缺少某些情况或者它是100%正确的。 请指出任何缺陷,并指导我一些更好的代码,如果它存在。

 def method_lookup_chain(obj, result = [obj.singleton_class]) if obj.instance_of? Class return add_modules(result) if result.last == BasicObject.singleton_class r = result.last.superclass method_lookup_chain(obj, result << r) else return result + obj.class.ancestors end end def add_modules(klasses) r = [] klasses.each_with_index do |k, i| r << k next if k == klasses.last r < [#, MoreClassMethods, ClassMethods, #, #] module InstanceMethods; end class Object include InstanceMethods end module X; end module Y; end class Dog include X include Y end d = Dog.new p method_lookup_chain(d) # => [#<Class:#>, Dog, Y, X, Object, InstanceMethods, Kernel, BasicObject] 

那篇文章让它看起来很混乱,但事实并非如此。 如果你对这些事情感兴趣,你应该阅读“Metaprogramming Ruby”。 在此之前,基本规则是one step to the right and up

  Object (superclass) ^ | Parent class A(superclass) ^ | Parent class B(superclass) ^ | obj -> object's class 

2)在obj和对象的类之间插入Singleton类:

  Object ^ | Parent class A(superclass) ^ | Parent class B(superclass) ^ | object's class(superclass) ^ | obj -> obj's singleton_class 

3)包含的模块直接插入到包含以下内容的类的上方:

  Object ^ | Parent class A ^ | Module included by Parent Class B ^ | Parent class B ^ | object's class ^ | obj -> obj's singleton_class 

编辑:

请指出任何缺陷

 p method_lookup_chain(Class) --output:-- [#, #, #, #] 

但…

 class Object def greet puts "Hi from an Object instance method" end end Class.greet --output:-- Hi from an Object instance method 

和..

 class Class def greet puts "Hi from a Class instance method" end end Class.greet --output:-- Hi from a Class instance method 

在类上调用的方法的查找路径实际上继续超过BasicObject的单例类( # ):

 class BasicObject class < 

类上调用的方法的完整查找路径如下所示:

  Basic Object ^ | Object ^ | Module ^ | Class ^ | BasicObject BasicObject's singleton class | ^ | | Object Object's singleton class | ^ | | Module Module's singleton class | ^ | | Class ---> Class's singleton class 

查找从Class的单​​例类开始,然后在右侧的层次结构中上升。 “Metaprogramming Ruby”声称对所有对象都有统一的查找理论,但是对类调用的方法的查找不符合3)中的图。

你有同样的问题:

 class A end class B < A end p method_lookup_chain(B) --output:-- [#, #, #, #] 

它应该是这样的:

  Basic Object ^ | Object ^ | Module ^ | Class ^ | BasicObject BasicObject's singleton class | ^ | | Object Object's singleton class | ^ | | AA's singleton class | ^ | | B.greet --> B's singleton class 

您需要记住的一件事是:在类上调用的任何方法的查找路径都必须包含Class,因为所有类都inheritance自Class。