Passing a string into function as a expression

First, those who say that you should avoid evaluating expressions at runtime are absolutely correct. Don’t do it if there’s any other solution.

If you do need to do it, and there are situations where it is valid, you have two sane options to make it semantically local, even though the eval takes place in global scope.

  1. Eval an anonymous function and pass your arguments to it.
julia> function Compare(a, b, c::String)
           f = eval(Meta.parse("(a, b) -> $c"))
           return Base.invokelatest(f, a, b)
       end
Compare (generic function with 1 method)

julia> Compare(1, 1, "a>b")
false

The invokelatest call does the same thing as f(a, b) but is necessary for technical reasons, basically because it calls a function that didn’t exist when Compare itself was called.

  1. Inject your arguments into the expression before evaluating it. This has been demonstrated in earlier replies but let’s do it in a more general way, reusing a solution from Evaluate expression with variables from a dictionary - #2 by GunnarFarneback :
interpolate_from_dict(ex::Expr, dict) = Expr(ex.head, interpolate_from_dict.(ex.args, Ref(dict))...)
interpolate_from_dict(ex::Symbol, dict) = get(dict, ex, ex)
interpolate_from_dict(ex::Any, dict) = ex
function Compare(a, b, c::String)
    expr = Meta.parse(c)
    return eval(interpolate_from_dict(expr, Dict(:a => a, :b => b)))
end
5 Likes