Reputation: 33395
I'm looking for a way, in F#, to print a value together with source file and line number; it's intended for semi-interactive debugging, so the syntax needs to be short.
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/caller-information provides a partial solution. The code on that page can be called like:
Tracer().DoTrace "foo"
and I'm looking for
trace "foo"
But of course, wrapping the above in a trace
function will report trace
being always the caller, which defeats the purpose.
I tried let inline trace ...
but that didn't make any difference.
I would try using a macro if F# had such, but it doesn't.
What's the best way, by modifying the above linked code or otherwise, to obtain trace
functionality with the shortest possible caller syntax?
Upvotes: 5
Views: 94
Reputation: 17038
Opening a type exposes all accessible static members of the type, so I think this does what you want:
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
type Tracer() =
static member trace(message: string,
[<CallerMemberName; Optional; DefaultParameterValue("")>] memberName: string,
[<CallerFilePath; Optional; DefaultParameterValue("")>] path: string,
[<CallerLineNumber; Optional; DefaultParameterValue(0)>] line: int) =
printfn $"Message: {message}"
printfn $"Member name: {memberName}"
printfn $"Source file path: {path}"
printfn $"Source line number: {line}"
open type Tracer
[<EntryPoint>]
let main _ =
trace "foo"
0
Output is:
Message: foo
Member name: main
Source file path: ...\Program.fs
Source line number: 18
Alternatively, you can automatically open the type if you want, so the caller doesn't have to explicitly open it:
[<AutoOpen>]
type Tracer() =
static member trace(message: string,
[<CallerMemberName; Optional; DefaultParameterValue("")>] memberName: string,
[<CallerFilePath; Optional; DefaultParameterValue("")>] path: string,
[<CallerLineNumber; Optional; DefaultParameterValue(0)>] line: int) =
printfn $"Message: {message}"
printfn $"Member name: {memberName}"
printfn $"Source file path: {path}"
printfn $"Source line number: {line}"
[<EntryPoint>]
let main _ =
trace "foo"
0
Upvotes: 8