1

在使用 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导致问题?

4

3 回答 3

3

我同意 Toivo 的观点,这是一个范围问题。例如,运行以下代码在全局环境中正确分配 a:

julia>@flag_errors global a = 2
a

julia>a
2

如果您对a存在于全球环境中感到满意,那么这可以解决问题。如果这已经在另一个范围内(函数、尝试等),我们将不得不进一步试验。

干杯。

于 2013-01-17T15:22:40.260 回答
3

这里有一些问题。一种是你有两个不相关的变量被命名broken——一个在宏中,一个在引用的正文中。另一个是表达式缺乏卫生转义——它应该被插值$(esc(ex)),以便向宏扩展器指示它应该在宏调用者的上下文中进行评估,而不是在宏定义上下文中。最后是 Toivo 提到的范围问题。使它表现得好像它不在新块中所需的范围分析甚至可能是不可能的;我不完全确定。

于 2013-07-05T16:45:43.873 回答
1

我认为该try块是这里的罪魁祸首,因为它引入了一个新的范围块。通常需要进行一些非常严肃的元编程来分析分配,ex以便能够撤消此操作。你为什么需要它?

于 2013-01-16T16:19:04.880 回答