Is there difference between Meta.eval and eval?

ex=quote
    x=1
    y=2
    x+y
end
ex.args
ex.head
Meta.eval(ex.args[6])
eval(ex.args[6])
julia> ex.head
:block

julia> Meta.eval(ex.args[6])
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] top-level scope at none:0
 [2] eval at ./boot.jl:328 [inlined]
 [3] eval(::Expr) at ./meta.jl:6
 [4] top-level scope at none:0

julia> eval(ex.args[6])
3

I don’t understand

Every module has a function Module.eval that evaluates code in the scope of the module. x hasn’t been defined in the module Meta, so Meta.eval(ex.args[6]) throws an error. The reason why eval(ex.args[6]) works is probably because you defined x before in the same session. You can read more about how eval works here: https://docs.julialang.org/en/v1/manual/metaprogramming/index.html#QuoteNode-1

5 Likes

Now I understand. Thanks :heart:

julia> ex=:(x₁=1)
:(x₁ = 1)

julia> x₁
ERROR: UndefVarError: x₁ not defined

julia> Meta.x₁
ERROR: UndefVarError: x₁ not defined

julia> Meta.eval(ex)
1

julia> x₁
ERROR: UndefVarError: x₁ not defined

julia> Meta.x₁
1

julia> eval(ex)
1

julia> x₁
1

Meta.eval() creates local variable x₁ in module Meta - (Meta.x₁) , but eval() → global variables

Module.eval(expr) evaluates expr in the global scope of Module.
eval(expr) evaluates expr in the global scope of the “current” module.

If expr creates a variable, as in your example :(x₁=1), it will be created as a global variable.