How to find where a method is defined at runtime?
This is really late, but here's how you can find where a method is defined:
# How to find out where a method comes from.# Learned this from Dave Thomas while teaching Advanced Ruby Studio# Makes the case for separating method definitions into# modules, especially when enhancing built-in classes.module Perpetrator def crime endendclass Fixnum include Perpetratorendp 2.method(:crime) # The "2" here is an instance of Fixnum.#<Method: Fixnum(Perpetrator)#crime>
If you're on Ruby 1.9+, you can use source_location
require 'csv'p CSV.new('string').method(:flock)# => #<Method: CSV#flock>CSV.new('string').method(:flock).source_location# => ["/path/to/ruby/1.9.2-p290/lib/ruby/1.9.1/forwardable.rb", 180]
Note that this won't work on everything, like native compiled code. The Method class has some neat functions, too, like Method#owner which returns the file where the method is defined.
EDIT: Also see the __file__
and __line__
and notes for REE in the other answer, they're handy too. -- wg
You can actually go a bit further than the solution above. For Ruby 1.8 Enterprise Edition, there is the __file__
and __line__
methods on Method
instances:
require 'rubygems'require 'activesupport'm = 2.days.method(:ago)# => #<Method: Fixnum(ActiveSupport::CoreExtensions::Numeric::Time)#ago>m.__file__# => "/Users/james/.rvm/gems/ree-1.8.7-2010.01/gems/activesupport-2.3.8/lib/active_support/core_ext/numeric/time.rb"m.__line__# => 64
For Ruby 1.9 and beyond, there is source_location
(thanks Jonathan!):
require 'active_support/all'm = 2.days.method(:ago)# => #<Method: Fixnum(Numeric)#ago> # comes from the Numeric modulem.source_location # show file and line# => ["/var/lib/gems/1.9.1/gems/activesupport-3.0.6/.../numeric/time.rb", 63]
I'm coming late to this thread, and am surprised that nobody mentioned Method#owner
.
class A; def hello; puts "hello"; end endclass B < A; endb = B.newb.method(:hello).owner=> A