Ruby method search path for an object

Is there a built-in Ruby method or a well-known library that returns a whole method search chain for an object? Ruby looks at an intricate sequence of classes (as discussed in this question ), for example, methods that match the message, and calls it method_missingon the receiver if none of the classes respond to the message.

I have compiled the following code, but I am sure that it skips certain cases or if it is 100% right. Please point out any flaws and direct me to the best code, if one exists.

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 << (k.included_modules - klasses[i+1].included_modules)
  end
  r.flatten
end

# EXAMPLES

module ClassMethods; end
module MoreClassMethods; end
class A
  extend ClassMethods
  extend MoreClassMethods
end
p method_lookup_chain(A) # => [#<Class:A>, MoreClassMethods, ClassMethods, #<Class:Object>, #<Class:BasicObject>]

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:0x007fcf7d80dd20>>, Dog, Y, X, Object, InstanceMethods, Kernel, BasicObject]
+4
source share
1 answer

, . , " ". : one step to the right and up:

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

2) Singleton obj :

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

3) , :

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

Edit:

,

p method_lookup_chain(Class)

--output:--
[#<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:BasicObject>]

...

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 BasicObject
  class <<self
    puts superclass
  end
end

--output:--
Class

, , :

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

Singleton, . " Ruby" , , , , 3).

:

class A 
end

class B < A
end

p method_lookup_chain(B)

--output:--
[#<Class:B>, #<Class:A>, #<Class:Object>, #<Class:BasicObject>]

:

                  Basic Object                 
                      ^
                      |
                    Object
                      ^
                      |
                    Module
                      ^
                      |
                    Class
                      ^
                      |
BasicObject    BasicObject singleton class
  |                   ^
  |                   |
Object         Object singleton class
  |                   ^
  |                   |
  A            A singleton class
  |                   ^
  |                   |
  B.greet -->  B singleton class

, : , , -, .

+13

Source: https://habr.com/ru/post/1541906/


All Articles