当我在Matlab中进行原型设计和调试代码时,我可以运行一个脚本,并在它停止运行时(成功或由于失败)立即检查和编辑该脚本中的所有变量。
在Julia中,循环内的变量是局部范围的。虽然这很好,但是一旦我满意我的工作,我就无法检查REPL中的变量。我能想到解决这个问题的唯一方法是将循环中的每个变量列为全局变量。然后,每次更改变量名称或引入新变量名称时,我都必须编辑该行。在我进行实验并且还不完全确定我正在做什么时,添加/更改变量是很常见的。有一个更好的方法吗?
答案 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