[ruby] set_trace_funcでメソッド定義を監視する
簡単かと思ったら、微妙だったので書いておく。ポイントは、ファイルの行の文字列そのものを渡してくれないので面倒くさい点と、class定義はわかるけどメソッド定義ははっきりとわからない点。だから、defを手動で発見してクラス定義のbindingでのselfを取ることで対象クラスを取得している。
# trace_method_def.rb $files = Hash.new set_trace_func Proc.new{ |event, file, line, id, binding, klass| if event == 'line' unless $files[file] $files[file] = open(file){ |f| [''] + f.readlines } end line_content = $files[file][line].sub(/#.*$/,'') # remove comment if $files[file][line] =~ /^\s*def\s*([^(\s]*)/ _class = eval "self",binding _method = $1 puts "#{_class}##{_method} = #{file}:#{line}" end end } class TestClass def foo puts "Test#foo" end def bar puts "Test#bar" end def baz puts "Test#baz" end def +() puts "Test#+" end end
でとりあえず取得できる。
結果:
TestClass#foo = trace_method_def.rb:18 TestClass#bar = trace_method_def.rb:22 TestClass#baz = trace_method_def.rb:26 TestClass#+ = trace_method_def.rb:30
一行でメソッド定義をする場合に対処するというか、def文の解析はもう少しがんばったほうがいいんだけど、そこは妥協。