Execute a string?

2019-08-10 02:41发布

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

标签: julia
2条回答
来,给爷笑一个
2楼-- · 2019-08-10 03:18

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.

查看更多
再贱就再见
3楼-- · 2019-08-10 03:25

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).

查看更多
登录 后发表回答