Use ruby's Method#source_location to determine where a method is defined.
method(:s).source_location
# => ["..snip../gems/sexp_processor-4.2.1/lib/sexp.rb", 332]
I've been using flog to get some simple code-quality metrics. I happily added it to my Gemfile's development group. Later, I wrote something like
t = 'foo' + s
and I wasn't defining s
, so I expected NameError
or
NoMethodError
. Instead,
TypeError: can't convert Sexp into String
Surprising. So, where is the s
method defined? Happily, ruby knows.
First, instantiate the s
method.
# send the `method` message to the same reciever (in this case,
# implicit) that we sent the `s` message to.
method(:s)
# => #<Method: Object#s>
OK, s
is an instance method on Object
. Cool, but who defined s
?
method(:s).source_location
# => ["..snip../gems/sexp_processor-4.2.1/lib/sexp.rb", 332]
Awesome, it's defined on sexp.rb, line 332. It turns out
sexp_processor
is a dependency of flog
.
Defining a method with as common a name as s
on Object
is a bit too much
pollution for my taste, seeing as my code doesn't use s
. So, I've removed
flog
from my bundle, though I still use the gem often.
In the above example, why is Object
the implicit receiver?
On the top level, a special instance of Object named "main" is the self. ("Three implicit contexts in Ruby", Yuki Sonoda)
This is easy to see in irb
:
self
# => main
self.class
# => Object