How can I eval a local variable in Julia

You can't. Julia's eval always evaluates code the current module's scope, not your local scope. Calling eval in local scope is an anti-pattern and a performance killer. You can, however, construct a new function which includes a bit of user code that refers to local scope and then call that function. For example:

# user-supplied expression
expr = :(i^2 + 1)

# splice into function body
test = @eval function ()
    i = 10
    $expr
end

Now you can call test:

julia> test()
101

Why is this better than calling eval inside of test as in the question? Because in the original, eval needs to be called every time you call test whereas in this usage, eval is only called once when defining test; when test is called no eval is done. So while you may call eval "at run time" in the sense of "while your application is running, getting user input" it is not called "at run time" in the sense of when the function constructed with that user input is called. The former is fine, whereas the latter as distinctly an anti-pattern.


As @StefanKarpinski mentioned eval always evaluates in global scope, but if one really wants to evaluate something locally, there are various way to do it:

import Base.Cartesian.lreplace
i = 50
function test1(expr)
  i=10
  eval(lreplace(expr,:i,i))
end

i = 50
function test2()
  i = 10
  @eval $i
end
test1(:(i))  # => 10
test2()      # => 10

But my preferred method to evaluates an expression at run-time is to create a function, I think it's the most efficient:

exprtoeval=:(x*x)
@eval f(x)=$exprtoeval
f(4) # => 16

Depending on the application, you could eval the entire function to get at the local value of i such as @simonster describes in this answer.

Tags:

Julia