Evaluate expression in function

I have constructed an function like follows:

function f(a::Vector{Float64})
   for i = 1:length(a)
      b = eval(Meta.parse(string("a[",i,"]")))

Getting this error when I run test

c = rand(5);


UndefVarError: a not defined

eval evaluates in global scope (where you don’t have a):

help?> eval


  Evaluate an expression in the global scope of the containing module.
  Every Module (except those defined with baremodule) has its own
  1-argument definition of eval, which evaluates expressions in that

What are you trying to do? Typically eval(parse(...)) should be avoided, there are probably better ways to do what you want.


I don’t know what you want to do but something like this

b = eval(Meta.parse(string("$(a[i])")))

but for what do you need eval there ?

@mwolff, @fredrikekre Thank you so much for your help.

I am creating a data structure that contains a set of fields

struct point
   x :: Float64
   y :: Float64
   z :: Integer

The fields of the structure are used to create expressions.


p  = point(1.5,2.5,6)

expr = String[];
push!(expr, "p.x + p.y*5");
push!(expr, "p.x*p.z + p.y*5");
push!(expr, "sin(p.x) + p.y*5");

I need to evaluate expressions within a function

values = f(p,expr)

ok this could help a bit

value=Meta.parse("$(sin(p.x) + p.y * 5)")

best regards


Best not to use eval when there’s a much easier way to get what you want:

exprs = Function[]
append!(exprs, [p -> p.x + 5p.y, 
              p -> p.x*p.z + 5p.y,
              p -> sin(p.x) + 5p.y])

p = point(1.5, 2.5, 6)
f(p, exprs) = [expr(p) for expr in exprs]

The main question is why do you need to do that, why do you have to use strings, and why do you need to do that in a function, also what syntax do you want to support. As usual for these kind of question, the solution greately depend on what you actually need.

2 more minor comments,

  1. Don’t use strings, at least use expressions, unless it’s interactive user input (i.e. REPL)

Is not doing any metaprogramming.

1 Like

You are right, for fixed formulas, of course, this is the better way. But if someone sends me a formula over the network as a string and I want a result right away, that’s a possibility. Many roads lead to Rome…

No, for fixed expressions you should have just write that expressions. Turning the result to a string and back doesn’t buy you anything…

then someone will send you a string that evals to a shell on your box.

edit: What you want is a small DSL with robust parser. I don’t know of any good packages that help you with this; but julia macros or eval are not gonna help you here. You should especially prevent contact between the julia parser / deserialization (including jld2) and attacker-supplied data. Even better, ask around whether there are already well-established DSLs supporting the set of features you need, and then write (or import or wrap) a parser for it. After running things through your own parser, you can generate and compile an expression tree if necessary.

@stillyslalom Thank you so much for your help.

The inputs are of type string.
How can I convert string expressions and save them in a function array?

expr_strings = "[p -> p.x + 5p.y, 
                 p -> p.x*p.z + 5p.y,
                 p -> sin(p.x) + 5p.y]"

exprs = include_string(Base, expr_strings)

* edit: it’s better hygiene to work in your own module and reduce risk of a user inadvertently overwriting Base methods, in which case you’d use include_string(MyModule, expr_strings).


Maybe https://github.com/JuliaDiffEq/DiffEqOnlineServer could be a useful starting point (particularly sanitation.jl)