# Evaluating expressions in file

**URL:** <https://discourse.julialang.org/t/evaluating-expressions-in-file/31172>\
**Category:** General Usage\
**Created:** [November 17, 2019, 9:44am UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172 "2019-11-17T09:44:46Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 9:44am UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/1 "2019-11-17T09:44:47Z")

</div>

Hi,  
I’m hitting one of these eval() scope-related issue, that I don’t know how to solve… maybe you can help me. This is related to an old Julia 0.6.2 code of mine, which was reading initial data from an external file, which contans lines like the following

```julia
x = 1.0
Nv = 10

```

which are initial values for some variables. Now inside my code I read the file, put every line in a string

```julia
record[1] = "x = 1.0"
record[2] = "Nv = 10"

```

and was evaluating that inside a computation function, with `eval(parse(redord[1])`, `eval(parse(redord[2])` and so on and so forth for each record.  
Now I’ve realized that since Julia 1.0 this is no longer possible, as eval works only in the global scope, and not inside a function. At this point, my code does not work anymore… So what would be a way to properly code this?  
I mean, I have to read the file and evaluate each line it contains inside my function, but the story is that not every file contains the same variable initialization, other file my have lines like ` Nh = 50` and not refer to x or Nv above, so I do not know what variables should I initialize beforehand…

Thanks,

Ferran

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 1:38pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/2 "2019-11-17T13:38:40Z")

</div>

Any help? please? I need to read files containing assignations to variables, something I could easily do before the scope rules changed… Now that all these have changed, I can’t manage to read them.  
I can’t change the input files either, as these come from a different project ☹

---

<div class="post-metadata">

**Author:** ![Karajan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karajan/32/8545_2.png) [@Karajan](https://discourse.julialang.org/u/Karajan)\
**Post date:** [November 17, 2019, 1:50pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/3 "2019-11-17T13:50:28Z")

</div>

Hi!  
I think the answer depends on the context.  
Some ideas that come to my mind:

Just put everything in global scope:

```julia
x = 0
y = 0
z = 0
eval(Meta.parse("x = 1.0"))
f(x, y, z)

```

For that you need to have all the variables you can possibly need initialized first, otherwise the function call will fail. If there is nothing else in that file you can probably just do `include(file)`.  
If that’s too much clutter you can put the same thing inside a struct and update the values you read in.

Other option: create a bespoke function:

```julia
record = "x = 1"
expr = quote
    function f()
        # here you paste the records:
        $record
        # here the calculation
        return x * 2
    end
end
eval(ex)
f()

```

I think if you can expand on what you exactly want to do it’s easier to recommend something specific.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [November 17, 2019, 1:52pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/4 "2019-11-17T13:52:50Z")

</div>

Just treat the file as julia code and `include` it to initialise variables with those names?

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 3:43pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/5 "2019-11-17T15:43:45Z")

</div>

Thanks for the replies 🙂

Still the situation is a little bit more involved that including the file. The story is that this format files are inherited from old fortran, where there is a (very useful!) instruction called NAMELIST. In there you have a large file containing different records, one for each run, and separated by some END\_OF\_RECORD string. One such (simplified) file would be something like the following

```julia
o-o-o-o-o-o-o-o-o-o

Nv = 5
Nh = 10

o-o-o-o-o-o-o-o-o-o

Nv = 10
dens = 0.021

o-o-o-o-o-o-o-o-o-o

Nh = 15
L = 0.016

o-o-o-o-o-o-o-o-o-o

```

Here we have three records, one the program must run three times, one for each record. At each run, only variables appearing in the record are updated, the other ones keep the same value they had in the preceding record.  
I can not include the whole file at once, as only the last repeated values would be taken into account. I could split the file in three different ones, and run the code for each one, but then the calues in the previous records would not be inherited. Of course I could update the records will all the previous values, but that can be amazing for large input files.

That was easily handled with the eval(parse()) thing in previous julia versions, but not anymore. So the question is whether this functionality could be kept or recovered, now that eval() does not work on a local scope…

Thanks again,

Ferran.

---

<div class="post-metadata">

**Author:** ![Karajan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karajan/32/8545_2.png) [@Karajan](https://discourse.julialang.org/u/Karajan)\
**Post date:** [November 17, 2019, 4:03pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/6 "2019-11-17T16:03:46Z")

</div>

Well, I suggested two (or three, depending how you want to count) versions that do what you want. After the more detailed explanation I wouldn’t advise the second version but the first version (both that in the global scope as well as that with the struct) should work fine. What do you think about those?

Edit: What I mean with “the struct version”:

```julia
mutable struct A
    x::Int
    y::Int
    z::Int
    A() = new(0, 0, 0)
end
a = A()
record = "x = 1"
n = split(record)[1]
v = parse(Int, split(record)[end])
setproperty!(a, Symbol(n), v)
f(a)

```

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 4:11pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/7 "2019-11-17T16:11:46Z")

</div>

but that is what is was done originally, everything in glibal scope. But you need to loop over all lines in a record to eval() them, and that no longer works as the scope inside the loop is not yhe global one…  
That’s what it was working in Julia 0.6.2, but not anymore

---

<div class="post-metadata">

**Author:** ![Karajan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/karajan/32/8545_2.png) [@Karajan](https://discourse.julialang.org/u/Karajan)\
**Post date:** [November 17, 2019, 4:18pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/8 "2019-11-17T16:18:06Z")

</div>

> [@Ferran\_Mazzanti](#):
>
> and that no longer works as the scope inside the loop is not yhe global one…

I think I don’t quite understand why this is a problem. You can just have all your variables in the global scope, and the updated will be `eval`ed there too, no matter where the eval is called from?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [November 17, 2019, 4:34pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/9 "2019-11-17T16:34:23Z")

</div>

> [@Ferran\_Mazzanti](#):
>
> Now I’ve realized that since Julia 1.0 this is no longer possible, as eval works only in the global scope, and not inside a function. At this point, my code does not work anymore… So what would be a way to properly code this?

To nitpick `eval` has always only worked in the global scope. The difference is that global variables no longer are automatically in scope inside a function. If you know which variables are used in your computations you can just declare all of them global at the start of the function and the rest should work as in 0.6.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [November 17, 2019, 4:47pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/10 "2019-11-17T16:47:53Z")

</div>

This is completely outside the intended use of the package, but you could try if `SoftGlobalScope` works for your specific problem.

Julia 0.6:

```julia
julia> function foo()
           eval(parse("x = 13"))
           return x
       end
foo (generic function with 1 method)

julia> foo()
13

julia> x
13

```

Julia 1.2:

```julia
julia> using SoftGlobalScope

julia> @softscope function foo()
           eval(Meta.parse("x = 13"))
           return x
       end
foo (generic function with 1 method)

julia> foo()
13

julia> x
13

```

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 5:32pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/11 "2019-11-17T17:32:01Z")

</div>

Oh, I see different options that will habe to try… Thank you guys a lot for providing so much help! I’ll report back once I can try them 🙂

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 5:41pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/12 "2019-11-17T17:41:50Z")

</div>

Thanks `GunnarFarneback`, but when decorating a variable with the `global` token, I have to give them a value, and that will override the value it had in the previous execution, while I only want that to happen in the set of variables I need to update, not in all of them…

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [November 17, 2019, 5:54pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/13 "2019-11-17T17:54:36Z")

</div>

Really?

```julia
julia> x, y = 1, 2
(1, 2)

julia> function foo()
           global x, y
           eval(Meta.parse("x = 13"))
           return x + y
       end
foo (generic function with 1 method)

julia> foo()
15

```

Of course, using global variables in the first place is not a particularly good approach (rather the opposite) but just reviving the functionality from 0.6 shouldn’t be that hard.

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [November 17, 2019, 6:11pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/14 "2019-11-17T18:11:59Z")

</div>

Sorry, I think I start to be too tired for Julia coding… I said that because I tried

```julia
sss = 13
function oly()
    global sss
end
oly()

```

and got

```julia
syntax: misplaced "global" declaration

Stacktrace:
 [1] top-level scope at /home/mazzanti/.julia/packages/IJulia/F1GUo/src/kernel.jl:52

```

but then after your comment, just tried

```julia
sss = 13
function oly()
    global sss
    println(sss)
end
oly()

```

and got the expected result

```julia
13

```

…so now I see this can be a solution. Sorry for being that moron ☹

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [November 17, 2019, 6:26pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/15 "2019-11-17T18:26:43Z")

</div>

That’s not a great error message but the reason is that you have `global` in the last statement, making it equivalent to

```julia
function oly()
    return global sss
end

```

and apparently you can’t have `global` in a return statement, which I suppose makes sense.

Edit: Right, should have tried with an assignment too. I think this is slightly fishy and may be worth filing an issue about.

---

<div class="post-metadata">

**Author:** ![EarthGoddessDude](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/earthgoddessdude/32/13003_2.png) [@EarthGoddessDude](https://discourse.julialang.org/u/EarthGoddessDude)\
**Post date:** [November 20, 2019, 2:00pm UTC](https://discourse.julialang.org/t/evaluating-expressions-in-file/31172/16 "2019-11-20T14:00:24Z")

</div>

Hi @Ferran_Mazzanti, did you figure out a solution to your problem? If you did, please post it in case others with similar problems see it (like myself 🙂).

And regarding your main program – are you doing some kind of attribution analysis, changing one variable at a time to see the incremental impact on some output variable? I couldn’t quite follow your explanation in a previous post.
