最近、一連のコミットが発生した後、バックエンド プロセスの実行に失敗するという問題が発生しました。私たちは良い子だったので、rake test
チェックインのたびに実行していましたが、Rails のライブラリ読み込みに何らかの異常があったため、プロダクション モードで Mongrel から直接実行した場合にのみ問題が発生しました。
バグを追跡したところ、新しい Rails gem が String クラスのメソッドを上書きし、ランタイム Rails コード内の 1 つの狭い使用法を壊したことが原因であることがわかりました。
とにかく、長い話を短くすると、実行時に、メソッドが定義されている場所を Ruby に問い合わせる方法はありますか? のようなものがwhereami( :foo )
返されますか/path/to/some/file.rb line #45
? この場合、String クラスで定義されていることを教えても役に立ちません。何らかのライブラリによってオーバーロードされているためです。
ソースがプロジェクト内に存在するかどうかは保証できません。そのため、grep しても'def foo'
必ずしも必要なものが得られるとは限りません。また、 's が多数 def foo
ある場合は、実行時までどれを使用しているかわからないこともあります。
ベストアンサー1
かなり遅くなりましたが、メソッドが定義されている場所を見つける方法は次のとおりです。
# 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
end
end
class Fixnum
include Perpetrator
end
p 2.method(:crime) # The "2" here is an instance of Fixnum.
#<Method: Fixnum(Perpetrator)#crime>
Ruby 1.9以降を使っている場合は、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]
これはネイティブコンパイルされたコードなど、すべてのコードで機能するわけではないことに注意してください。メソッドクラス便利な機能もいくつかあります。メソッド#所有者メソッドが定義されているファイルを返します。
編集:他の回答の REE の__file__
および注記も参照してください。これも便利です。 -- wg__line__