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 grep
for 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 Method
object 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.
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:
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:
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.