We recently had a problem where, after a series of commits had occurred, a backend process failed to run. Now, we were good little boys and girls and ran rake test
after every check-in but, due to some oddities in Rails' library loading, it only occurred when we ran it directly from Mongrel in production mode.
I tracked the bug down and it was due to a new Rails gem overwriting a method in the String class in a way that broke one narrow use in the runtime Rails code.
Anyway, long story short, is there a way, at runtime, to ask Ruby where a method has been defined? Something like whereami( :foo )
that returns /path/to/some/file.rb line #45
? In this case, telling me that it was defined in class String would be unhelpful, because it was overloaded by some library.
I cannot guarantee the source lives in my project, so grepping for 'def foo'
won't necessarily give me what I need, not to mention if I have many def foo
's, sometimes I don't know until runtime which one I may be using.
Copying my answer from a newer similar question that adds new information to this problem.
Ruby 1.9 has method called source_location:
This has been backported to 1.8.7 by this gem:
So you can request for the method:
And then ask for the
source_location
of that method:This will return an array with filename and line number. E.g for
ActiveRecord::Base#validates
this returns:For classes and modules, Ruby does not offer built in support, but there is an excellent Gist out there that builds upon
source_location
to return file for a given method or first file for a class if no method was specified:In action:
On Macs with TextMate installed, this also pops up the editor at the specified location.
You can actually go a bit further than the solution above. For Ruby 1.8 Enterprise Edition, there is the
__file__
and__line__
methods onMethod
instances:For Ruby 1.9 and beyond, there is
source_location
(thanks Jonathan!):You can always get a backtrace of where you are by using
caller()
.I'm coming late to this thread, and am surprised that nobody mentioned
Method#owner
.You might be able to do something like this:
foo_finder.rb:
Then ensure foo_finder is loaded first with something like
(I've only messed with rails, so I don't know exactly, but I imagine there's a way to start it sort of like this.)
This will show you all the re-definitions of String#foo. With a little meta-programming, you could generalize it for whatever function you want. But it does need to be loaded BEFORE the file that actually does the re-definition.
Very late answer :) But earlier answers did not help me