Julia全局地将所有变量放在循环中(暂时)

时间:2017-01-21 20:03:52

标签: scope julia

当我在Matlab中进行原型设计和调试代码时,我可以运行一个脚本,并在它停止运行时(成功或由于失败)立即检查和编辑该脚本中的所有变量。

在Julia中,循环内的变量是局部范围的。虽然这很好,但是一旦我满意我的工作,我就无法检查REPL中的变量。我能想到解决这个问题的唯一方法是将循环中的每个变量列为全局变量。然后,每次更改变量名称或引入新变量名称时,我都必须编辑该行。在我进行实验并且还不完全确定我正在做什么时,添加/更改变量是很常见的。有一个更好的方法吗?

1 个答案:

答案 0 :(得分:1)

我提出了以下非常基本和简单的宏。我们的想法是通过为每个作业添加一个print语句来修改表达式。

要使用它,只需在所需的函数或表达式块之前添加@add_print。

但是,最好的解决方案是使用Gallium调试器

walk(ex) = nothing

function walk(ex::Expr)
    for i in 1:length(ex.args)
        subex = ex.args[i]
        #println(subex)
        walk(subex)
        if isa(subex, Expr) && subex.head in Set([:(=), :(+=), :(-=), :(*=), :(/=)]) && ex.head == :block
            #println(subex)
            line = "line unknown:"
            if i > 1 && ex.args[i-1].head == :line
                line = "line $(ex.args[i-1].args[1])"
            end
            var = string(subex)
            ex.args[i] = :(
                begin
                    $subex
                    println($line)
                    println($var, " -> ", $(subex.args[1]))
                end
            )
        elseif ex.head == :block && isa(subex, Symbol)
            ex.args[i] = :(
                begin
                    println($subex)
                    $subex
                end
            )
        end
    end
end

macro add_print(ex)
    walk(ex)
    ex
end

演示:

@add_print function binary_search(v, val)
    if v[1] > val || v[end] < val
        return 0
    end
    left = 1
    right = length(v)
    while left < right
        mid = div(left + right, 2)
        if v[mid] < val
            left = mid + 1
        else
            right = mid
        end
    end
    left
end

binary_search([1, 3, 4, 5, 7, 9], 4)

julia> binary_search([1, 3, 4, 5, 7, 9], 4)
line 5
left = 1 -> 1
line 6
right = length(v) -> 6
line 8
mid = div(left + right,2) -> 3
line 12
right = mid -> 3
line 8
mid = div(left + right,2) -> 2
line 10
left = mid + 1 -> 3
3