実行時にメソッドが定義されている場所を見つけるにはどうすればいいですか? 質問する

実行時にメソッドが定義されている場所を見つけるにはどうすればいいですか? 質問する

最近、一連のコミットが発生した後、バックエンド プロセスの実行に失敗するという問題が発生しました。私たちは良い子だったので、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

かなり遅くなりましたが、メソッドが定義されている場所を見つける方法は次のとおりです。

http://github.com/76951 より

# 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__

おすすめ記事