Ruby - determining method origins?

Viewed 4305

When sent a message, a Ruby object searches to see whether it has a method by that name to respond with. Its method lookup searches in the following order, and uses the first method it finds.

  1. Singleton methods defined on itself (aka methods on its "eigenclass")
  2. Methods defined in its class
  3. Any modules mixed into its class, in reverse order of inclusion (only the earliest inclusion of a given module has any effect - if the superclass includes module A, and the subclass includes it again, it’s ignored in the subclass; if the subclass includes A then B then A, the second A is ignored) (update: note that this was written before Module.prepend existed)
  4. Its parent class
  5. Any methods mixed into the parent class, the parent's parent, etc.

Or, to put it more simply, it looks on itself, then everything in self.class.ancestors in the order they're listed.

This lookup path is followed at the moment the method is called; if you make an instance of a class, then reopen the class and add a method or mix one in via a module, the existing instance will gain access to that method.

If all of this fails, it looks to see if it has a method_missing method, or if its class does, its parent class, etc.

My question is this: aside from examining the code by hand, or using example methods like puts "I'm on module A!", can you tell where a given method came from? Can you, for example, list an object's methods and see "this one is on the parent class, this one is on module A, this one is on the class and overrides the parent class," etc?

4 Answers
Related