5

どのメソッドが呼び出され、どのクラスがインスタンス化されたかを追跡するなど、TRACE 用のカスタム ロガーを作成する代わりに、クラスの下にあるすべてのメソッド自体をログに記録する簡単な方法はありますか? これは node.js アプリケーション用です。

class MyClass

  constructor: () ->
    console.log 'MyClass:constructor'

  doThat: () ->
    console.log 'MyClass:doThat'

exports.MyClass = MyClass

myClass = new MyClass()
myClass.doThat()

私のやり方では、2 つではなく4 つのログ メッセージが表示されます (したがって、何が起こっているかを追跡するために記述するコードが少なくて済みます)。

4

2 に答える 2

3

最近、複雑なOO再帰的なものをトレースするために、このようなものを実装する必要がありました。基本的に、私はメソッドをあまり汚染せずに「追跡可能」にしたかったのです。したがって、ここでもソリューションを適用できる可能性があります。

まず、他の関数を追跡可能にする関数を追加します。

Function::trace = do ->
  makeTracing = (ctorName, fnName, fn) ->
    (args...) ->
      console.log "#{ctorName}:#{fnName}"
      fn.apply @, args
  (arg) ->
    for own name, fn of arg 
      @prototype[name] = makeTracing @name, name, fn

次に、それを使用するには、@traceトレースする各メソッドの前にを追加するだけです。

class MyClass
  @trace methodA: ->
    @methodB 42

  @trace methodB: ->
    console.log "method b called with #{n}"

または、@ traceを1回だけ追加してから、すべての追跡可能なメソッドをもう1レベルインデントします。

class MyClass
  @trace 
    methodA: ->
      @methodB 42

    methodB: (n) ->
      console.log "method b called with #{n}"

ご覧traceのとおり、CoffeeScriptの構文を悪用しています。method: -> 'foo'aの内部class MyClassはメソッド定義として解釈されます。ただし、関数(これは、関数を追加したインスタンス)を@trace method: -> 'foo'呼び出して、 1つのキーを持つリテラルオブジェクトを渡すと解釈されます。JavaScriptでは、のようになります。traceMyClassFunctiontracemethodthis.trace({method: function() {return 'foo';}})

関数はそのtraceオブジェクトを受け取り、そのキー(メソッド名)と値(メソッド)を繰り返しMyClass、呼び出しをログに記録して元のメソッドを呼び出す関数をプロトタイプに追加します。

とにかく、の出力は次の(new MyClass).methodA()ようになります。

MyClass:methodA
MyClass:methodB
method b called with 42

ただし、コンストラクターは通常のメソッドではないため、このソリューションは機能しません。

あなたはこれでかなり空想を得ることができます。また、各メソッドに渡された引数と戻り値をログに記録し、必要に応じてネストされた呼び出しのインデントを追加することもできます(複雑な問題= Dをデバッグする必要がある場合は、結果のトレースが非常に役立ちます)。


更新:より興味深い例として、典型的な複合パターンの例、幾何学的図形、および図形のグループのミニバージョンを次に示します。http://jsfiddle.net/2YuE7/より興味深いトレース機能を備えています。moveすべての図は方法を理解しています。この合成図があり、それを呼び出すmove場合:

f = new Composite [
  new Rectangle 5, 10, 3, 4
  new Composite [
    new Circle 0, 0, 2
    new Circle 0, 0, 4
    new Circle 0, 0, 6
  ]
]

f.move 2, 3

トレース出力は次のとおりです。

(Composite[Rectangle[5,10,3,4],Composite[Circle[0,0,2],Circle[0,0,4],Circle[0,0,6]]]).move(2, 3)
| (Rectangle[5,10,3,4]).move(2, 3)
| -> Rectangle[7,13,3,4]
| (Composite[Circle[0,0,2],Circle[0,0,4],Circle[0,0,6]]).move(2, 3)
| | (Circle[0,0,2]).move(2, 3)
| | -> Circle[2,3,2]
| | (Circle[0,0,4]).move(2, 3)
| | -> Circle[2,3,4]
| | (Circle[0,0,6]).move(2, 3)
| | -> Circle[2,3,6]
| -> Composite[Circle[2,3,2],Circle[2,3,4],Circle[2,3,6]]
-> Composite[Rectangle[7,13,3,4],Composite[Circle[2,3,2],Circle[2,3,4],Circle[2,3,6]]]
于 2012-08-15T17:46:23.570 に答える