There are several level of problems here.
A macro, including string macros, are supposed to return expressions, not do the evaluation themselves. Any evaluation done in a macro is done at parse time.
The code you wrote proceeds similar the following order. Because you try to evaluate xx["a"]
before you set it, you get the error that you get.
xx = Dict{String,String}()
temp = "tasty " * xx["a"]
ex = :(@testset "a" begin
xx["a"] = "apple"
@test $temp == "tasty apple"
end)
eval(ex)
Rather your macro should return an expression that will be evaluated in the normal order.
julia> macro x_str(str, suf)
return :($str * xx[$suf])
end
@x_str (macro with 1 method)
julia> @testset "a" begin
xx["a"] = "apple"
println(xx["a"])
end
apple
Test Summary: |Time
a | None 0.0s
Test.DefaultTestSet("a", Any[], 0, false, false, true, 1.711649824769256e9, 1.711649824780527e9, false, "REPL[11]")
julia> @macroexpand x"tasty "a
:("tasty " * Main.xx["a"])
julia> macro x_str(str, suf)
return :($str * xx[$suf])
end
@x_str (macro with 1 method)
julia> let xx = Dict("a" => "orange")
x"tasty "a
end
"tasty apple"
Also note that with the definition I just gave, xx
is Main.xx
.
If I want xx
to refer to something in the context of the local scope, then I would need to the following.
julia> macro x_str(str, suf)
return esc(:($str * xx[$suf]))
end
@x_str (macro with 1 method)
julia> let xx = Dict("a" => "orange")
x"tasty "a
end
"tasty orange"
julia> @macroexpand x"tasty "a
:("tasty " * xx["a"])
Edit: Added the esc
in the last example.