Search code examples
f#wrapperdecoratortrace

wrap all module's functions with a decorator programmatically


There is need for tracing. The decorator should print function name, parameters values and return value. Instead of writing each time a decorator for each function, it would be terrific if it could be possible to do this programmatically.


Solution

  • The current function name can be discovered using reflection via MethodBase.GetCurrentMethod. Functions could be easily decorated with an inline function for logging:

    let inline log args f  =
      let mi = System.Reflection.MethodBase.GetCurrentMethod()
      let result = f ()
      printf "%s %A -> %A" mi.Name args result
    
    let add a b = log (a,b) (fun () -> a + b)
    
    add 1 1
    

    Which prints: add (1, 1) -> 2

    EDIT: Another option would be to create a wrap function, i.e.:

    let inline wrap f = 
      fun ps ->
        let result = f args
        printfn "%A -> %A" args result
        result
    
    let add (a,b) = a + b
    
    wrap add (1,1)
    

    However in this case there is not an easy way to programmatically retrieve the function name.

    Yet another option might be to develop a Type Provider that takes an assembly path as a parameter and provides wrapped versions of all members.