Julia元编程不能调用局部变量吗?

问题产生

运行

for i=1:10
    k=i
    eval(Meta.parse("k+=1"))
end

产生报错:

UndefVarError: k not defined

Stacktrace:
  [1] top-level scope
    @ none:1
  [2] eval
    @ ./boot.jl:360 [inlined]
  [3] eval
    @ ./client.jl:446 [inlined]
  [4] top-level scope
    @ ~/path/test.ipynb:3
  [5] eval
    @ ./boot.jl:360 [inlined]
  [6] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1116
  [7] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
  [8] invokelatest
    @ ./essentials.jl:706 [inlined]
  [9] (::VSCodeServer.var"#146#147"{VSCodeServer.NotebookRunCellArguments, String})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/packages/VSCodeServer/src/serve_notebook.jl:18
 [10] withpath(f::VSCodeServer.var"#146#147"{VSCodeServer.NotebookRunCellArguments, String}, path::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/packages/VSCodeServer/src/repl.jl:185
 [11] notebook_runcell_request(conn::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::VSCodeServer.NotebookRunCellArguments)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/packages/VSCodeServer/src/serve_notebook.jl:14
 [12] dispatch_msg(x::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::VSCodeServer.JSONRPC.MsgDispatcher, msg::Dict{String, Any})
    @ VSCodeServer.JSONRPC ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/packages/JSONRPC/src/typed.jl:67
 [13] serve_notebook(pipename::String; crashreporting_pipename::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/packages/VSCodeServer/src/serve_notebook.jl:94
 [14] top-level scope
    @ ~/.vscode/extensions/julialang.language-julia-1.5.6/scripts/notebook/notebook.jl:12
 [15] include(mod::Module, _path::String)
    @ Base ./Base.jl:386
 [16] exec_options(opts::Base.JLOptions)
    @ Base ./client.jl:285
 [17] _start()
    @ Base ./client.jl:485

是元编程不能调用局部变量吗?

应该是 Meta.parse 作用域的问题,默认是在顶层执行的吧。

你把 k 定义为全局变量就可以了。


元编程可能用宏返回表达式会更好,可以精细的控制变量解析的上下文。
Meta.parse 就没得选。

感谢,我试一试!!!

应该是eval的问题,以下引用v1.7的文档内容:

给定一个表达式对象,可以使用 eval 使 Julia 在全局作用域内评估(执行)它:

eval只在全局进行,这里使用宏应该更方便

让宏返回表达式,非卫生的表达式(访问当前作用域)用esc包裹。