Use @__LINE__ etc in another macro definition

This has been up on First Steps for five days without eliciting a comment, hoping a wider audience can provide me some assistance…

How do I do this…

verbosity_tags = [....]
macro noise(tag, args...)
    return :(if $tag in verbosity_tags; println("$(basename(@__FILE__)): $(@__LINE__): ", $(esc.(args)...)); end )
end

in such a way that @FILE & @LINE are expanded at the point @noise is used rather than at the point it is defined.

It seems clear that they should be wrapped in another layer of quoting to delay the expansion however my naive attempts to do so have failed.

I did manage to achieve what I wanted by assembling the macro body by hand using Expr et al. but that’s a rather clumsy way to do a pretty trivial thing.

jon.

Use the implicit __source__ argument to macros:


julia> macro showsource()
           @show __source__.file __source__.line
       end
@showsource (macro with 1 method)

julia> @showsource();
__source__.file = Symbol("REPL[2]")
__source__.line = 1

julia> 1
1

julia> 

       @showsource();
__source__.file = Symbol("REPL[4]")
__source__.line = 3
1 Like

I got to where I wanted with…

macro xxx(t, args...)
    if :($t); print("$(basename(string(__source__.file))): $(__source__.line): "); :( println($(esc.(args)...));) end
end

It had not occurred to me to quote only portions of the macro body thereby allowing source to be referenced. Still patching args… into a single call to println escaped me and I had to split it into two calls.

However, I would rather know how to reference @LINE etc from another macro definition. Avoiding doing so is, well, avoiding the issue. If it can’t be done then that seems wrong to me.

In my old head it simply requires another layer of quoting to delay the expansion of @LINE until the context is that of the invocation rather than the definition.

jon.