如何让 `eval` 使用特定路径来解析 Julia 中的 `include`?

Ale*_*hin 5 julia

此表达式eval(Meta.parse("begin $(code)\nend"))将使用include相对于文件eval...定义的解析来评估 Julia 代码。

如何更改它以便它使用另一个目录?就像是

eval(Meta.parse("begin $(code)\nend"), resolve_include_relative_to=somepath)
Run Code Online (Sandbox Code Playgroud)

或者,如果这是不可能的 - 相对于当前目录(如 REPL)?

更新

可能的解决方案 - 用绝对路径替换相对路径

function fix_include(code::String, relative_path::String)::String
  code = replace(code, r"include\(\"\./(.*?)\"\)" => s"include(\"__relative_path__/\1\")")
  code = replace(code, r"__relative_path__" => relative_path)
  code
end

eval(Meta.parse("begin $(fix_include(code, relative_path))\nend")
Run Code Online (Sandbox Code Playgroud)

用例:

我正在评估字符串代码片段,有时它们包含include带有相对路径的语句,并且它们解决了错误的路径。我想明确指定告诉它应该使用什么路径进行解析。或者至少总是使用当前目录 '.',而不是eval(xxx)定义行的文件所在的目录./lib/runner.jl

pfi*_*seb 2

这个函数应该可以解决问题(include相对于任务本地存储中的路径,如文档字符串所示):

\n\n
function eval_at(code; path = "none", mod = Main)\n    tls = task_local_storage()\n    hassource = haskey(tls, :SOURCE_PATH)\n    hassource && (path\xe2\x80\xb2 = tls[:SOURCE_PATH])\n    # setting this is enough for `include` to be correct\n    tls[:SOURCE_PATH] = path\n\n    try\n      # let\'s use the three-arg `include_string` here to make sure `@__FILE__`\n      # etc resolve correctly\n      return include_string(mod, code, path)\n    finally\n      hassource ?\n        (tls[:SOURCE_PATH] = path\xe2\x80\xb2) :\n        delete!(tls, :SOURCE_PATH)\n    end\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

用法示例:

\n\n
julia> pwd()\n"/home/pfitzseb/Documents"\n\njulia> isfile("test.jl")\nfalse\n\njulia> include("test.jl")\nERROR: could not open file /home/pfitzseb/Documents/test.jl\n\njulia> eval_at("""include("test.jl")""", path = "/home/pfitzseb/foo.jl")\nMain.LogT\n\njulia> eval_at("""@__FILE__""", path = "/home/pfitzseb/foo.jl")\n"/home/pfitzseb/foo.jl"\n
Run Code Online (Sandbox Code Playgroud)\n