# \[SOLVED\] How can I evaluate in Main from a module?

**URL:** <https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908>\
**Category:** General Usage\
**Tags:** metaprogramming, eval\
**Created:** [January 20, 2022, 6:07am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908 "2022-01-20T06:07:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [January 20, 2022, 6:07am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/1 "2022-01-20T06:07:42Z")

</div>

Hello!  
I am trying to make a macro, @each, which will take each value and compare the falsehood of it to a certain condition. The problem is, while it works fine so long as the macro is globally defined, i.e. in a notebook:

```julia
macro each(exp::Expr)
    x = exp.args[2]
    if length(exp.args) == 2
        for value in eval(x)
            state = eval(Meta.parse(string(exp.args[1], "(", value, ")")))
            if state != true
                return(false)
            end
        end
    end
    for value in eval(x)
        state = eval(Meta.parse(string(value," ", exp.args[1], " ", exp.args[3])))
        if state != true
            return(false)
        end
    end
    return(true)
end

```

I am not so sure that the function version is entirely working (yet,) though it might be. Here is that macro now working:

```julia
if @each [5, 10, 15] >= 5
    print("hi")
end

hi

if @each [5, 10, 15] > 50
    println("This will not print")
end

x = [5, 5]

# Yes I know, we have .==, but we don't have
# .ismissing(), and things like that.
if @each x == 5
    println("Yes.")
end

Yes.

```

The only issue comes when I want to evaluate something like the last expression after including a module to do so.

```julia
include("src/Each.jl")

if Main.Each.@each x < 20
    
end

LoadError: UndefVarError: x not defined
in expression starting at In[4]:1

```

Of course, providing values still works:

```julia
if Main.Each.@each [5, 10, 15] < 20
    println("yeah")
end

```

I noticed that macro definitions by default receive a module, i.e. main under the alias **module** , pretend that has two \_\_s on either side, as the formatting is… Actually:

```julia
__module__

```

Thank goodness for method errors for telling me that, by the way. Anyway, I was just wondering if there is some sort of way I can evaluate this module into here. As you can see, evaluating a string Main.x yield x:

```julia
eval(Meta.parse("Main.x"))
3-element Vector{Int64}:
  5
 10
 15

```

But for some reason, evaluating Main.x does not really do anything… Additionally, it would be nice to keep them as symbols.

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [January 20, 2022, 6:21am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/2 "2022-01-20T06:21:45Z")

</div>

An update…  
I thought maybe about using getfield() for this, it seemed apt as I could get the field :x from **module** , once again pretend that module has underlines around it. That ended up working perfectly. Somehow after pulling my hair out for an hour, and FINALLY deciding to post on the forums, I ended up figuring it out in like a minute after posting. Really, I blame myself for not thinking of getfield() earlier. Here is the new code:

```julia
macro each(exp::Expr)
    x = exp.args[2]
    xname = ""
    if contains(string(x), '[')
        xname = eval(x)
    else
        xname = getfield( __module__ , Symbol(x))
    end
    if length(exp.args) == 2
        for value in xname
            state = eval(Meta.parse(string(exp.args[1], "(", value, ")")))
            if state != true
                return(false)
            end
        end
    end

    for value in xname
        state = eval(Meta.parse(string(value," ", exp.args[1], " ", exp.args[3])))
        if state != true
            return(false)
        end
    end
    return(true)
end

```

So if anyone is wondering how to get values, and work with values from main from within a module, from expressions, **this** is at least one working way to do so.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [January 20, 2022, 6:49am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/3 "2022-01-20T06:49:43Z")

</div>

The issue here is your macro is performing all of the calculations and then returning `true` or `false`. What you want the macro to return is an _expression_ to evaluate in the main scope. Your macro should probably contain something along the lines of

```julia
return esc(:( something ))

```

or

```julia
out = quote
    long(expression)
    with_more.lines()
end
return esc(out)

```

The best tip I’ve gotten for this was: put almost nothing in your macro itself:

```julia
macro each(ex)
    return esc(_each_helper(ex))
end

function _each_helper(ex)
    # turn expression ex into another expression which, 
    # when evaluated in Main, does the right thing
end

```

You should never have to call `eval` explicitly.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [January 20, 2022, 6:53am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/4 "2022-01-20T06:53:23Z")

</div>

Oh, and for debugging macros, `@macroexpand @each [1, 2, 3] > 0.5` is your friend.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [January 20, 2022, 6:56am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/5 "2022-01-20T06:56:46Z")

</div>

One more thing. If this is actually functionality you need and not just an exercise in metaprogramming, can I suggest `all(x .>= 5)` or the more performant but less self-explanatory `all(>=(5), x)`?

---

<div class="post-metadata">

**Author:** ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)\
**Post date:** [January 20, 2022, 8:11am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/6 "2022-01-20T08:11:20Z")

</div>

> [@emmettgb](#):
>
> Somehow after pulling my hair out for an hour, and FINALLY deciding to post on the forums, I ended up figuring it out in like a minute after posting.

> **[When You Get Stuck, Talk to the Duck - Mind Over Machines](https://www.mindovermachines.com/when-you-get-stuck-talk-to-the-duck/)**
>
> 3 minute read What It Means to “Rubber Duck Debug” Do you ever get stuck on a coding problem and, to help figure it out, you begin talking to yourself, or to a rubber duck on your desk?  Just me?...

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [January 20, 2022, 9:51am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/7 "2022-01-20T09:51:54Z")

</div>

Diiiiid not realize this method existed.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [January 20, 2022, 10:28am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/8 "2022-01-20T10:28:18Z")

</div>

It’s great. Especially the `all(f::Function, x)` version, which short-circuits if `f` evaluates to `false` at any point.

```julia
julia> all(x->(println(x); x<3), 1:10)
1
2
3
false

```

(There’s also `any` for the opposite function)

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [January 21, 2022, 10:37am UTC](https://discourse.julialang.org/t/solved-how-can-i-evaluate-in-main-from-a-module/74908/9 "2022-01-21T10:37:32Z")

</div>

> [@emmettgb](#):
>
> module to do so.
> 
> ```julia
> include("src/Each.jl")
> 
> if Main.Each.@each x < 20
> 
> ```

Looks very useful, thank you for sharing this with me!
