Using internal interpolation of Julia's foreign policy inside macros?
I am trying to write a Julia macro that takes Cmd objects and runs them inside a loop. The trick is that I want to use the local loop variables for interpolation in the command. I would write a function and use eval (), but eval () uses global scope and therefore cannot see local loop variables.
Below is a simple example to demonstrate how string interpolation works, but command interpolation fails:
macro runcmd(cmdExpr)
quote
for i in 1:2
println("i: $i")
run($cmdExpr)
end
end
end
@runcmd(`echo $i`)
outputs
i: 1
ERROR: i not defined
in anonymous at none:5
If I expand the macro, I get
quote # none, line 3:
for #261#i = 1:2 # line 4:
println("i: $#261#i") # line 5:
run(Base.cmd_gen((("echo",),(i,))))
end
end
I'm guessing the part # 261 # missing from the cmd_gen argument reference for i is related to the problem, but I don't know for sure.
source to share
You are correct that the problem is with a mismatch between the index #261#i
and its reference in echo $i
. An easy way to solve the problem is to delete i
used in the index:
macro runcmd(cmdExpr)
quote
for $(esc(:i)) in 1:2
println("i: $i")
run($cmdExpr)
end
end
end
Then we get:
julia> @runcmd(`echo $i`)
i: 1
1
i: 2
2
More discussion in Julia's metaprogramming documentation .
source to share