Question
How to Find Where a Method Is Defined at Runtime in Ruby
Question
In Ruby, is there a way at runtime to determine where a method was defined, including the file path and line number?
For example, imagine a Rails application where a gem overrides a method on String, and that override only causes a failure in a specific runtime environment. In that situation, simply knowing that the method belongs to String is not enough—I need to know which file actually defined the active method implementation.
I am looking for something conceptually like this:
whereami(:foo) # => "/path/to/file.rb:45"
The source may come from Ruby itself, my application, Rails, or an installed gem, so searching the project for def foo is not reliable. If multiple methods with the same name exist, I want to know which one Ruby is actually calling at runtime.
Short Answer
By the end of this page, you will understand how Ruby can reveal where a method came from at runtime, including its source file and line number when available. You will also learn the difference between instance methods and singleton methods, how overridden methods affect lookup, and which tools help when source_location is not enough.
Concept
Ruby treats methods as real runtime objects. That means you can often inspect a method after Ruby has loaded it and ask questions like:
- Which object owns this method?
- Which class or module defined it?
- What file and line number did it come from?
The key idea is that Ruby method lookup happens dynamically. A method such as String#foo may have been:
- defined in the original class
- added by reopening the class later
- mixed in from a module
- overridden by a gem
- defined on a single object only
Because of that, the active method implementation is not always obvious from reading source files. What matters is the method Ruby will actually call at runtime.
In modern Ruby, the most direct tool is source_location, available on Method and UnboundMethod objects. It returns:
- an array like
['/path/to/file.rb', 45]for Ruby-defined methods nilfor many methods implemented in C or built into Ruby
This matters in real programming because debugging monkey patches, Rails autoloading issues, gem conflicts, and environment-specific bugs often depends on finding the exact method implementation Ruby is using.
Mental Model
Think of Ruby method lookup like following directions through a stack of sticky notes.
- A class starts with its own methods.
- Gems or your app can add new sticky notes later by reopening the class.
- Modules can insert more sticky notes into the lookup chain.
- Ruby reads from the top of that stack when deciding which method to run.
source_location is like asking Ruby: "Which sticky note are you currently reading, and where was it written?"
That is why checking the active runtime method is more useful than searching for every def foo in a codebase.
Syntax and Examples
The basic pattern is to get a Method or UnboundMethod object, then call source_location.
Inspect an instance method on a specific object
text = "hello"
method_obj = text.method(:upcase)
p method_obj.owner
p method_obj.source_location
Possible output:
String
nil
nil means the method may be implemented in C rather than Ruby source.
Inspect a Ruby-defined method
class String
def loud_greeting
"HEY #{self.upcase}!"
end
end
text = "world"
method_obj = text.method(:loud_greeting)
p method_obj.owner
p method_obj.source_location
Possible output:
String
["/my/app/models/extensions/string_patch.rb", ]
Step by Step Execution
Consider this example:
module ExtraStringMethods
def shout
"#{upcase}!"
end
end
class String
include ExtraStringMethods
end
s = "hello"
m = s.method(:shout)
p m.owner
p m.source_location
puts m.call
Step by step:
ExtraStringMethodsdefinesshout.Stringincludes that module.s = "hello"creates aStringobject.s.method(:shout)asks Ruby for the actual method object thatswill use.m.ownershows where Ruby found the method, likelyExtraStringMethods.m.source_locationreturns the file and line whereshoutwas defined.
Real World Use Cases
Here are common situations where runtime method location is useful:
Debugging monkey patches
A gem reopens String, Array, or another core class and changes behavior. You can inspect the active method to find the patch file.
Investigating Rails load-order issues
In Rails apps, environment-specific loading can cause one method definition to override another. Checking the runtime method tells you which version won.
Finding gem conflicts
Two gems may define the same method name. source_location helps identify which gem is currently providing the method.
Understanding metaprogramming
Frameworks often create methods dynamically. Inspecting methods at runtime helps confirm what actually exists.
Production debugging
When behavior differs between development, test, and production, runtime inspection can reveal different code paths or loaded extensions.
Real Codebase Usage
In real Ruby projects, developers usually combine source_location with a few other inspection tools.
Pattern: print owner and source together
m = some_object.method(:foo)
puts "owner: #{m.owner}"
p m.source_location
Why this helps:
ownertells you which class or module supplied the method.source_locationtells you where it was written.
Pattern: guard against missing methods
if some_object.respond_to?(:foo)
m = some_object.method(:foo)
p m.source_location
end
This avoids raising NameError when the method does not exist.
Pattern: inspect method lookup chain
If the result is surprising, check ancestors:
p some_object.class.ancestors
This shows modules and parent classes involved in lookup.
Pattern: inspect class vs instance methods correctly
.instance_method()
.method()
Common Mistakes
Mistake 1: Calling source_location on the result instead of the method
Broken code:
"abc".upcase.source_location
Why it fails:
"abc".upcasereturns a string result, not a method object.
Correct code:
"abc".method(:upcase).source_location
Mistake 2: Confusing class methods with instance methods
Broken code:
String.method(:upcase).source_location
Why it is wrong:
upcaseis an instance method onString, not a class method.
Correct code:
String.instance_method(:upcase).source_location
# or
"abc".method(:upcase).source_location
Mistake 3: Expecting every method to have a file and line number
Comparisons
| Tool | What it tells you | Best use |
|---|---|---|
method(:name) | Gets the bound method for a specific object | Find what this object will call |
instance_method(:name) | Gets an unbound instance method from a class | Inspect class instance methods without an object |
owner | Class or module that owns the method | See whether a module or patch supplied it |
source_location | File and line number for Ruby-defined methods | Find the actual source file |
ancestors | Method lookup chain for a class | Understand why one implementation wins |
grep 'def foo' |
Cheat Sheet
# Instance method on an object
m = obj.method(:foo)
m.owner
m.source_location # => ["/path/file.rb", 12] or nil
# Instance method from a class
um = MyClass.instance_method(:foo)
um.owner
um.source_location
# Class method
m = MyClass.method(:bar)
m.owner
m.source_location
# Check whether method exists first
obj.respond_to?(:foo)
# See lookup chain
obj.class.ancestors
Rules to remember:
- Use
obj.method(:name)for methods called on an object. - Use
Class.instance_method(:name)for instance methods defined on a class. - Use
Class.method(:name)for class methods. source_locationreturns[file, line]for Ruby methods.source_locationoften returnsnilfor C-implemented methods.ownermay be a module, not the object's class.- For overridden methods, inspect the active method at runtime, not just source files.
FAQ
How do I find the file where a Ruby method is defined?
Use obj.method(:name).source_location for an instance method or Class.method(:name).source_location for a class method.
Why does source_location return nil in Ruby?
It usually means the method is implemented in C or otherwise does not have Ruby source location information.
How can I tell which gem overrode a Ruby method?
Inspect the active method at runtime with source_location and owner. The file path often points into the gem directory.
What is the difference between owner and source_location?
owner tells you the class or module providing the method. source_location tells you the file and line where it was defined.
Can I inspect instance methods without creating an object?
Yes. Use MyClass.instance_method(:method_name).
How do I debug a monkey-patched core class in Ruby?
Get the current method object from a real instance, then inspect owner, source_location, and the class chain.
Mini Project
Description
Build a small Ruby debugging helper that reports where a method comes from at runtime. This mirrors a real debugging task in Rails or gem-heavy applications where a method may be overridden by application code, a module, or a third-party library.
Goal
Create a helper that prints a method's owner and source location for both instance methods and class methods.
Requirements
- Create a Ruby class or module with at least one custom method.
- Add a second method through a mixin or reopened class.
- Write a helper that accepts an object and method name.
- Print whether the method exists, its owner, and its source location.
- Demonstrate the helper on both a normal object method and a class method.
Keep learning
Related questions
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.