简体   繁体   中英

How can I automatically wrap all the methods of a class?

To ease debugging coffeescript applications I'd like to have a logWrapClass(Klass) function that automatically adds a console.log(method.name, method.arguments) to the methods in my class using a method wrapper, is that doable?

this does not seem to be sufficient

consoleLogWrapClass = (Klass) ->
  klassName = Klass.toString()
  klassName = klassName.substr 'function '.length
  klassName = klassName.substr 0, klassName.indexOf('(')

  K = Klass.prototype
  for prop of K #in Object.getOwnPropertyNames(K)
    obj = K[prop]
    if typeof(obj) is 'function'
      decoratedName = "#{klassName}::#{prop}"
      K[prop] = () ->
        console.debug 'trace: '+decoratedName, arguments
        return obj.apply this, arguments

when I do

class Someclass
    ...

consoleLogWrapClass Someclass

it looks like the wrapper has conflated all the functions of the initial class, like if all the obj and decoratedName point to the same element for some reason.

edit: okay, that's even weirder now because if I split the calls in two functions

consoleLogWrapFunction = (fn, decoratedName) ->
  () ->
    console.debug 'trace: '+decoratedName, arguments
    return fn.apply this, arguments

consoleLogWrapClass = (Klass) ->
  klassName = Klass.toString()
  klassName = klassName.substr 'function '.length
  klassName = klassName.substr 0, klassName.indexOf('(')

  K = Klass.prototype
  for prop of K #in Object.getOwnPropertyNames(K)
    obj = K[prop]
    if typeof(obj) is 'function'
      K[prop] = consoleLogWrapFunction obj, "#{klassName}::#{prop}"

it works, can someone explain why?

consoleDebugWrapFunction = (name, fn) ->
  ->
    console.log "#{name} called with arguments: #{[].slice.call(arguments).join ', '}"
    fn.apply this, arguments

consoleDebugWrapClass = (Klass) ->
  for prop of Klass.prototype
    obj = Klass.prototype[prop]
    if typeof obj is 'function'
      Klass.prototype[prop] = consoleDebugWrapFunction prop, obj

Usage example:

class A
  foo: (a, b) ->
    a + b

consoleDebugWrapClass A
a = new A
console.log a.foo 3, 6

Output:

foo called with arguments: 3, 6
9

maybe this audit helps

How to implement a simple prioritized listener pattern in JavaScript

you can use the the technique and wrap all prototype members

function wrap(o,f) {for(var n in o) if (typeof(n)=="function") o[n]=f.prefix(o[n]);}

o=object to be wrapped

f=audit function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM