If I have a function that is part of a module, and I want a log entry while inside the function,I have to manually print the function namespace and name e.g.
namespace MyModuleNamespace
module MyModule =
let AddTwoNums logger x y =
logger.Info("MyModuleNamespace.AddTwoNums - Start")
let res = x+y
logger.Info("MyModuleNamespace.AddTwoNums - End")
res
Is there any way I can automatically work out what "MyModuleNamespace.AddTwoNums" is as it is very cumbersome/error prone especially when you have to rename functions and modules during refactoring of code
Even if that cannot be done, is there any way I can automatically work out what "AddTwoNums" is i.e. the function name?
Method 1: Get Function Name in Python using function. func_name.
There are two methods to call a function from string stored in a variable. The first one is by using the window object method and the second one is by using eval() method.
A JavaScript function is defined with the function keyword, followed by a name, followed by parentheses (). Function names can contain letters, digits, underscores, and dollar signs (same rules as variables). The parentheses may include parameter names separated by commas: (parameter1, parameter2, ...)
String To Function Using The eval() Function In Python We can also use the eval() function to convert a string to a function. Here, the input string is the name of the function. In the eval() function, we will pass the name of the function and the ' () ' separated by the addition symbol ' + '.
There are a couple ways to do this, and I'm not sure which would be the best one for your scenario. One way that I've used in the past is to get the information from the stack trace:
let stackTrace = StackTrace()
let topFrame = stackTrace.GetFrame(0)
let currentFunction = topFrame.GetMethod()
printfn "%s.%s" currentFunction.DeclaringType.Name currentFunction.Name
In order to keep from having to put these lines in every function, you can make an inline
function that does this, which will give you the name of the calling function due to the inlining.
let inline getCurrentFunction () =
let stackTrace = StackTrace()
let topFrame = stackTrace.GetFrame(0)
let currentFunction = topFrame.GetMethod()
sprintf "%s.%s" currentFunction.DeclaringType.Name currentFunction.Name
If you don't need the actual namespace / module name or are willing to replace that with the file name, there are special attributes that instruct the compiler to supply corresponding arguments to a function:
open System.Runtime.CompilerServices
type Logger =
static member Trace(
msg: string,
[<CallerMemberName>] ?memberName: string,
[<CallerFilePath>] ?path: string,
[<CallerLineNumberAttribute>] ?line: int) =
printfn "%s from %s.%s on line %i" msg path.Value memberName.Value line.Value
module Foo =
let bar() =
Logger.Trace("hello")
// hello from c:\path\to\Logging.fsx.bar on line 32
Foo.bar()
MS Docs has more to say about Caller Information.
Note that when your run this from within fsi, the line number is only accurate the first time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With