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' + sand 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