I have constructed an function like follows:
function f(a::Vector{Float64})
for i = 1:length(a)
b = eval(Meta.parse(string("a[",i,"]")))
println(b)
end
end
Getting this error when I run test
c = rand(5);
f(c);
UndefVarError: a not defined
eval
evaluates in global scope (where you don’t have a
):
help?> eval
eval(expr)
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
module.
What are you trying to do? Typically eval(parse(...))
should be avoided, there are probably better ways to do what you want.
2 Likes
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
end
The fields of the structure are used to create expressions.
e.g.
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)")
println(value)
best regards
Michael
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]
3 Likes
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,
- 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)
.
3 Likes
Maybe https://github.com/JuliaDiffEq/DiffEqOnlineServer could be a useful starting point (particularly sanitation.jl
)