# Update source file with eval-resulted code

**URL:** <https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636>\
**Category:** General Usage\
**Tags:** question, metaprogramming, code-generation\
**Created:** [July 14, 2023, 8:28pm UTC](https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636 "2023-07-14T20:28:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [July 14, 2023, 8:28pm UTC](https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636/1 "2023-07-14T20:28:02Z")

</div>

Imagine the following scenario:

I have a function that generates an `Expr`, which is in turn processed by `eval`.

To make it easier, let’s create a small example:

```julia
function makeval()
    ex =
        Expr(:function,
            Expr(:call, :addxy,
                Expr(:(::), :x, :Int),
                Expr(:(::), :y, :Int)),
            Expr(:block,
                Expr(:call, :+, :x, :y)))
    eval(ex)
end

@info "Main names: " names(Main, all=false)
# will print:
#┌ Info: Main names: 
#│ names(Main, all = false) =
#│ 4-element Vector{Symbol}:
#│ :Base
#│ :Core
#│ :Main
#└ :makeval

makeval()

@info "Main names: " names(Main, all=false)
# will print:
#┌ Info: Main names: 
#│ names(Main, all = false) =
#│ 5-element Vector{Symbol}:
#│ :Base
#│ :Core
#│ :Main
#│ :addxy
#└ :makeval

@info "1 + 2 = " addxy(1, 2)
# will print:
#┌ Info: 1 + 2 = 
#└ addxy(1, 2) = 3

```

Now, it is obvious that I could just do something with `string(ex)` inside the function - and save it to some file if I wanted.

My question is this: is there an idiomatic way to save a snapshot of the current state (e.g., source code) of a module?

In my example, before executing the `makeval` function, the `addxy` function was not defined. However, after `makeval` call, `addxy` is my module scope and I can call it.

Don’t spend much time with the answer (OK, you can go into details if you really want) - but if there are a set of functions to do this, just point me in the right direction and I can figure it out and I can publish here how it went (for future reference).

---

<div class="post-metadata">

**Author:** ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)\
**Post date:** [July 15, 2023, 6:00am UTC](https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636/2 "2023-07-15T06:00:13Z")

</div>

It’s not very what you’re end goal is, but you _usually_ don’t want to call `eval` directly. Instead you could use a macro:

```julia
macro make()
    return quote
        function $(esc(:addxy))(x::Int, y::Int)
            x + y
        end
    end
end

```

You have to escape `addxy` to make it visible outside the macro, but otherwise this has the same effect as your function example.

```julia-repl
julia> @info("Main names :", names(Main, all=false))
┌ Info: Main names :
│ names(Main, all = false) =
│ 7-element Vector{Symbol}:
│ Symbol("@make")
│ :Base
│ :Core
│ :InteractiveUtils
│ :Main
│ :addxy
└ :ans

julia> @make()
addxy (generic function with 1 method)

julia> @info("Main names :", names(Main, all=false))
┌ Info: Main names :
│ names(Main, all = false) =
│ 7-element Vector{Symbol}:
│ Symbol("@make")
│ :Base
│ :Core
│ :InteractiveUtils
│ :Main
│ :addxy
└ :ans

julia> @info "1 + 2 = " addxy(1, 2)
┌ Info: 1 + 2 = 
└ addxy(1, 2) = 3

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 15, 2023, 10:05am UTC](https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636/3 "2023-07-15T10:05:40Z")

</div>

> [@algunion](#):
>
> Now, it is obvious that I could just do something with `string(ex)` inside the function - and save it to some file if I wanted

Not necessarily, like if the `Expr` contains something other than symbols, literals, or such `Expr`:

```julia
julia> x = []
Any[]

julia> eval(:(function f() $x, $x end))
f (generic function with 1 method)
julia> f()[1] === f()[2]
true

julia> eval(Meta.parse(string(:(function f() $x, $x end))))
f (generic function with 1 method)
julia> f()[1] === f()[2]
false

```

---

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [July 15, 2023, 10:33am UTC](https://discourse.julialang.org/t/update-source-file-with-eval-resulted-code/101636/4 "2023-07-15T10:33:19Z")

</div>

> [@Benny](#):
>
> Not necessarily, like if the `Expr` contains something other than symbols, literals, or such `Expr`:

Thanks for pointing that out. Let’s keep things in the scope of the MWE: I can do `string(ex)` where `ex` is defined as in the MWE, not where `ex` is any `Expr`.
