У меня есть строка, например. z[2]
и я хочу eval
его в контексте, например. Dict(:z => 1:10)
Лучший способ оценить в заданной области/контексте, который находится в форме Дикта?
Каков наилучший способ сделать это?
Я могу сделать вид работы, но он очень медленный.
function replace_expr(expr, d::Dict)
return expr
end
function replace_expr(s::Symbol, d::Dict)
get(d, s, s)
end
function replace_expr(expr::Expr, d::Dict)
return Expr(replace_expr(expr.head, d),
[replace_expr(e, d) for e in expr.args]...)
end
function eval_with(context::Dict{Symbol, Any}, expr_string::AbstractString)
# E.g. :abc => :(s[:abc])
d = Dict(k => :(s[$(Meta.quot(k))]) for k in keys(context))
ex = parse("s -> $expr_string")
ex = replace_expr(ex, d)
return eval(ex)(context)
end
Ниже тест
function make_context()
x = 1
y = "foo"
z = 2:5
Dict(
:x => x,
:y => y,
:z => z
)
end
const context = make_context()
@test eval_with(context, "x + 3") == 4
@test eval_with(context, "string(1, y, 1)") == "1foo1"
@test eval_with(context, "z[2]") == 3
@time eval_with(context, "z[2]")
# 0.004739 seconds (767 allocations: 40.728 KB)
Это уже огромное улучшение. Я попробовал 'eval (M,: (const $ k = $ v))' также, к сожалению, это еще не помогает. – colinfang