Execute a string?

橙三吉。 提交于 2020-01-05 15:16:51

问题


I wanted to execute a string, but found that there's no exec function in Julia:

a = 1
println(exec("a")) # ERROR: exec not defined

Is there a way to execute a string in Julia?

The original problem is that I'm trying to log a list of variables:

thingsToLog = ["a", "b", "c"]

to file:

open(logFile, "w") do io
    for thing in thingsToLog
        write(io, @sprintf("%s = %s\n", thing, eval(thing)))
    end
end

回答1:


As said above, you can call parse to create an AST from the string, and then call eval on that. In your example though, it seems easier to create your list as

thingsToLog = [:a, :b, :c]

to avoid having through parse at all. Usually, it's both easier and safer to pass quoted ASTs like this (in this case, symbols) directly to eval; you can also interpolate ASTs into quoted ASTs if it's not enough with a fixed set of ASTs (see the manual for more details).

A few more words of caution when it comes to eval:

  • By design, it only works in global scope.
  • It's not fast, since it needs to compile new code. So it's best reserved for evaluations that only need to be done once (such as evaluating generated method or type definitions), or when speed is not really important.
  • It can make for pretty hard to understand code.

Regarding evaluation in local scope, reading this thread made me realize that most of the required functionality was already present in the Debug package, so I just released an update that allows this (the cautions above still apply though). The function where you want to evaluate code in local scope has to be wrapped with the @debug_analyze macro. Then you can retrieve an object representing the local scope using @localscope, and retrieve values of local variables from it by indexing with the corresponding symbols. Example:

using Debug
@debug_analyze function f(x,y,z,thingsToLog)
    s = @localscope
    for sym in thingsToLog
        println(sym, " = ", s[sym])
    end
end
f(1,2,3,[:x,:z])

which prints

x = 1
z = 3

For more details, see this section in the Debug package readme.




回答2:


Call parse on the string first, then pass the resulting AST to eval: eval(parse("a")). Optionally you can pass a module to eval to have the expression be evaluated in a certain context (see eval).



来源:https://stackoverflow.com/questions/29300126/execute-a-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!