Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programmatically determine which class/module defines a method being called?

In Ruby, how can I programmatically determine which class/module defines a method being called?

Say in a given scope I invoke some_method(). In the same scope I'd like to invoke a function find_method(:some_method) that would return which Class, Singleton Class or Module defines some_method.

Here's some code to illustrate what I mean:

class Foo
  include ...

  def bar
    ...
    some_method() # calls a method in scope, assume it exists

    find_method(:some_method) # Returns where the method is defined
                              # e.g. => SomeClassOrModule
    ...
  end
end

I'm guessing I have to use a complex mixture of reflective functions, starting with self and using self.ancestors to walk up the inheritance tree, using method_defined? to check if a method is defined on a Class or Module, and probably some other tricks to inspect scopes from the innermost to the outermost (since the code may run within, e.g., an instance_eval).

I just don't know the correct order and all the subtleties of the Ruby metamodel to implement find_method such that it's both exhaustive in its search and correct from a method dispatch resolution perspective.

thanks!

like image 407
Alex Boisvert Avatar asked Feb 26 '23 01:02

Alex Boisvert


1 Answers

Found that this was surprisingly simple. Neat!

Expanding on this answer, to show how to actually return the owner class:

foo.method(:some_method).owner

Wrap that in an instance method if you find it necessary, but that's not really that bad, eh?

like image 170
Matchu Avatar answered Apr 05 '23 23:04

Matchu