我一直在尝试编写一个Julia宏,它接受Cmd对象并在循环中运行它们。问题是我想在命令中使用本地循环变量进行插值。我会编写一个函数并使用eval(),但eval()使用全局范围,因此无法看到本地循环变量。
下面是一个简单的例子,演示字符串插值的工作原理,但命令插值失败:
macro runcmd(cmdExpr)
quote
for i in 1:2
println("i: $i")
run($cmdExpr)
end
end
end
@runcmd(`echo $i`)
输出
i: 1
ERROR: i not defined
in anonymous at none:5
如果我扩展宏,我会
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
我猜测cmd_gen参数中缺少的#261#部分对i的引用与问题有关,但我不确定。
答案 0 :(得分:1)
您是对的,问题是由于索引#261#i
与echo $i
中对其的引用不匹配。解决问题的一种简单方法是转义索引中使用的i
:
macro runcmd(cmdExpr)
quote
for $(esc(:i)) in 1:2
println("i: $i")
run($cmdExpr)
end
end
end
然后我们得到:
julia> @runcmd(`echo $i`)
i: 1
1
i: 2
2
朱莉娅的metaprogramming documentation还有更多讨论。