Where Does That Method Come From?

Sometimes I land in the vicinity of some code, suspect a function or variable, and I want to go look at its implementation or documentation. So I hunt for “where is this function?” And it’s not always clear where it is when you’re just in a random file. Is it a ruby thing? Is it a rails thing? Is it a function actually implemented on the controller, but I have access to it in the view because … rails? If you can build some sort of intuition as to where to look, that would be awesome.

– Anonymous Poll Everywhere apps engineer

Ruby and Rails are both known for providing “sharp knives” — powerful tools that can hurt you if you don’t know what you’re doing. As the quote above illustrates, method definition is just such a knife for many new Ruby/Rails users. Methods can be defined by an object’s class, in a module that class includes, on superclasses or modules they include, or directly on the object itself. They can be defined with the def keyword or with  alias_method or metaprogrammed at runtime with  define_method or  class_eval. Or it may not even be defined on the object, but delegated to another object explicitly with delegate or implicitly with  SimpleDelegator or by overriding method_missing! Even if you’re familiar with all of these ways that an object can respond to a method call, you wouldn’t want to grepfor each of these patterns through the whole codebase and all the gems. Fortunately, Ruby has other sharp knives (sharp band-aids?) to help you out.

The Object#method method returns a Method object

The most straightforward solution, available in all Ruby environments is to use the Object#method method. This method, available on (almost) every Ruby object, accepts a method name as a string or symbol and returns a Methodobject representing the object’s method of that name. Yes, methods are themselves objects in Ruby, and in turn have their own methods; for example, you can call a method to invoke it, or unbind it from its current receiver. More importantly,  Method objects also implement source and  source_location methods that can tell you how and where a method is implemented.

The method method

Pry-ing open a method

In addition to the powerful functionality built in to Ruby itself, the Pry console, available in development and test environments, provides a ton of extra tools for introspection into running code. For finding the source of a method, Pry provides the show-source command, which provides source code, source location, and more:

Pry: show-source User#name

However, show-source is not limited just to the source code of instance methods. Per the documentation shown below, it can provide information on locally available methods, classes, superclasses, and return values of methods:

Pry: help show-source

Conclusion

Whether you’re getting your bearings in new code or deep in an investigation into a subtle bug, you’re likely to run into methods that you’re unfamiliar with. In those cases, whether you’re using vanilla Ruby or are supercharged with Pry, having easy access to the source code and locations of these methods will save you lots of time and frustration.