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.

+3


source to share


1 answer


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 .

+1


source







All Articles