记录每种方法?

5 javascript node.js coffeescript

而不是必须为TRACE创建自定义记录器,例如遵循调用哪些方法以及实例化哪些类,是否有一种简单的方法可以使类下的所有方法自己记录?这是针对node.js应用程序的.

class MyClass

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

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

exports.MyClass = MyClass

myClass = new MyClass()
myClass.doThat()
Run Code Online (Sandbox Code Playgroud)

如果我按照自己的方式进行操作,您将看到4条日志消息而不是2条消息(因此必须编写更少的代码来跟踪发生的情况).

epi*_*ian 3

我最近需要实现类似的东西来跟踪一些复杂的面向对象递归的东西。基本上,我想让一种方法“可追踪”,而又不会对其造成太多污染;所以也许这个解决方案也可以应用在这里。

首先,添加一个使其他函数可追踪的函数:

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
Run Code Online (Sandbox Code Playgroud)

@trace然后,要使用它,只需在要跟踪的每个方法之前添加:

class MyClass
  @trace methodA: ->
    @methodB 42

  @trace methodB: ->
    console.log "method b called with #{n}"
Run Code Online (Sandbox Code Playgroud)

或者仅添加 @trace 一次,然后将所有可跟踪方法缩进一级:

class MyClass
  @trace 
    methodA: ->
      @methodB 42

    methodB: (n) ->
      console.log "method b called with #{n}"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,trace这是一种滥用 CoffeeScript 语法的行为。method: -> 'foo'a 内部class MyClass被解释为方法定义。但@trace method: -> 'foo'被解释为调用函数traceMyClass这是一个Function实例,我们已向其添加了该trace函数),并用一个键向其传递一个文字对象method。在 JavaScript 中,它会类似于this.trace({method: function() {return 'foo';}}).

trace函数将只获取该对象并迭代它的键(方法名称)和值(方法),并将函数添加到MyClass记录其调用的原型中,然后调用原始方法。

无论如何,输出(new MyClass).methodA()将是:

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
Run Code Online (Sandbox Code Playgroud)

但此解决方案不适用于构造函数,因为它们不仅仅是普通方法。

你可能会很喜欢这个。您还可以记录传递给每个方法的参数、返回值,如果您愿意,甚至可以为嵌套调用添加缩进(如果您需要调试复杂的问题,则生成的跟踪非常有帮助=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
Run Code Online (Sandbox Code Playgroud)

跟踪输出为:

class MyClass
  @trace methodA: ->
    @methodB 42

  @trace methodB: ->
    console.log "method b called with #{n}"
Run Code Online (Sandbox Code Playgroud)