I’ve not found a function tracing facility for Julia so I’m trying to implement a simple one. My idea is to have a macro,@trace, that prefixes a method definition and alters that definition to start with a log message that prints the function and arguments and ends with a log message that prints the return values. The macro also takes a global variable name as argument. Logging will only occur if that variable is true at execution time.
using Pkg
Pkg.add(;url="https://github.com/MarkNahabedian/NahaJuliaLib.jl")
using NahaJuliaLib
@trace(trace_hanoi, function hanoi(from, to, other, count)
if count == 1
println("move 1 from $from to $to")
return
else
hanoi(from, other, to, count - 1)
println("move 1 from $from to $to")
hanoi(other, to, from, count - 1)
return (from, to) # arbitrary result to show
end
end)
trace_hanoi = false
With tracing turned off we just get
hanoi(:a, :b, :c, 2)
move 1 from a to c
move 1 from a to b
move 1 from c to b
(:a, :b)
but with tracing turned on, we get
trace_hanoi = true
true
hanoi(:a, :b, :c, 2)
┌ Info: Trace Enter
└ Expr(:call, hanoi, Expr(:parameters, Expr(:kw), from, to, other, count)) = :((hanoi)(; $(Expr(:kw)), a, b, c, 2))
┌ Info: Trace Enter
└ Expr(:call, hanoi, Expr(:parameters, Expr(:kw), from, to, other, count)) = :((hanoi)(; $(Expr(:kw)), a, c, b, 1))
move 1 from a to c
┌ Info: Trace Exit
└ result = nothing
move 1 from a to b
┌ Info: Trace Enter
└ Expr(:call, hanoi, Expr(:parameters, Expr(:kw), from, to, other, count)) = :((hanoi)(; $(Expr(:kw)), c, b, a, 1))
move 1 from c to b
┌ Info: Trace Exit
└ result = nothing
┌ Info: Trace Exit
└ result = nothing
(:a, :b)
I would like for the function call expression in the @info output to look like Julia surface syntax. I don’t see Meta.unparse or Meta.serialize. Is there a function that will do the inverse of Meta.parse – going from an expression to a string of source code?
Thanks.