在使用Julia宏时,我似乎又回到了试错编程,这也不例外。我正在尝试编写一个简单的宏来捕获表达式中的任何错误,并在表达式失败时设置标志。它是一个宏,因为我希望在调用上下文中计算表达式(可能包括一个或多个赋值语句)。所以,像:
macro flag_errors(ex)
broken = false
esc(quote
try
$(ex)
catch
broken = true
end
end)
end
我尝试了各种嵌套esc
函数的方法,但我还没有找到一种方法来正确评估调用环境中的赋值:
julia> @flag_errors a=2
2
julia> a
a not defined
julia> @flag_errors a=2+"X"
true
julia> a
a not defined
julia> broken
broken not defined
写这个宏的正确方法是什么? try
阻止导致问题吗?
答案 0 :(得分:3)
我同意Toivo认为这是一个范围问题。例如,正确运行以下代码会在全局环境中分配:
julia>@flag_errors global a = 2
a
julia>a
2
如果您在全局环境中存在a
,那么就可以解决问题。如果这已经在另一个范围(功能,尝试等),我们必须进一步试验。
干杯。
答案 1 :(得分:2)
这里有一些问题。一个是你有两个不相关的变量名为broken
- 一个在宏中,一个在引用的主体中。另一个是缺少表达式的卫生转义 - 它应该插入为$(esc(ex))
,以便向宏扩展器指示它应该在宏调用者的上下文中进行评估,而不是宏定义上下文。最后是Toivo提到的范围问题。要使其表现得好像不在新块中所需的范围分析可能甚至不可能;我不太确定。
答案 2 :(得分:1)
我认为try
块是罪魁祸首,因为它引入了一个新的范围块。需要一些非常严肃的元编程来分析ex
中的分配,以便能够一般地撤消这一点。你为什么需要它?