3

機能しないいくつかのテストをデバッグしようとしていますが、いくつかの問題があります。テストを実行し、重要なメッセージをログに出力するときに test.log を追跡していますが、すべての織り交ぜられたコールバックとフックのために、どのモデルのどのメソッドがどの SQL を呼び出しているのかわかりません :)

メソッド名をログに記録するために少し書きました:

def log_mname
  caller[0]=~/`(.*?)'/  # note the first quote is a backtick
  Rails.logger.debug '=' * 80
  Rails.logger.debug ">> #{Time.now} - #{$1}"
  Rails.logger.debug '=' * 80
end

log_mnameこれはうまく機能しますが、モデルのすべてのメソッドに追加する必要があり、現実的ではありません。私が望むのは、単純な行またはブロックを Rails アプリに追加することです。これにより、基本的に「呼び出されたすべてのメソッドをデバッグ ログに記録する」ことができます。

モデルの上部にルビーを使用しようとしset_trace_funcましたが、うまくいきませんでした。また、各モデルに何かを追加する必要はなく、test/debug.rb 環境ファイルなどに何かを追加したいと考えています。

何かご意見は?

4

1 に答える 1

1

あなたが尋ねている概念は反射として知られています。あなたがそれについてもっと読むことに興味があるなら。

あなたの質問に答えるに__method__は、名前を知りたいメソッド内で、メソッド名をシンボルとして返します

すなわち

$ irb
irb(main):001:0> def qwerty
irb(main):002:1> __method__
irb(main):003:1> end
=> nil
irb(main):004:0> qwerty
=> :qwerty
irb(main):005:0> 

そして、これはRuby 1.8.7から機能します

編集

上記はメソッド名を出力することです。

メソッド呼び出しを動的に表示するには、ActiveSupport の #constantize とset_trace_funcshow call tr​​aces を組み合わせて使用​​します。

# in your test environment initializer file
require 'active_support/inflector/inflections'
MODELS_TO_WATCH = Dir.entries("#{Rails.root}/app/models/").
                      gsub(".rb", ""). # strip all extensions from filenames
                      capitalize!. # no reason for the bang, just saving space
                    # constantize # make "User" string into User model, for e.g.
# if you constantize, remove `to_s` from `classname` in the proc below
# the version that worked for me was without constantizing but I figure both 
# variations yield the same result

class_eval do |c| # Replace this with a "class DummyClass" for proper sandboxing
  set_trace_func proc { |event, id, classname|
    if event == "call" && MODELS_TO_WATCH.include?(classname.to_s)
      puts "called #{classname}'s #{id}"
    end
  }
end

ノート! リーチ機能ですset_trace_func。プロセスが強制終了されるまで、Ruby プロセスにラッチされます (IRB の多くの死がこれを証明できます)。元に戻す方法はまだ見つかりませんでした。そして、導入された条件がなければ、それは厄介な印刷物を持っています。エラーのように見えるかもしれませんが、そうではありません。set_trace_func

これが、これをテスト初期化子に入れることをお勧めする理由です。そしておそらくダミークラスで!このようにして、Rails アプリケーションを開発環境、本番環境、またはセットアップしたその他の環境で再起動しても、このハッキングは影響しません。

これがクラス コンテキストで評価されることが不可欠です。インスタンスコンテキストで評価されるかどうかがわかりました。したがってinstance_eval、呼び出される関数を除いて、Rubyプログラムの実行中に発生するすべてのイベントを出力します。

于 2012-10-15T18:45:23.763 に答える