# Keeping modules "clean" when including files

**URL:** https://discourse.julialang.org/t/keeping-modules-clean-when-including-files/32525
**Category:** General Usage
**Created:** [December 20, 2019, 7:36pm UTC](https://discourse.julialang.org/t/keeping-modules-clean-when-including-files/32525 "2019-12-20T19:36:03Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![csavorgn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csavorgn/32/9798_2.png) [@csavorgn](https://discourse.julialang.org/u/csavorgn)
#### Post date: [December 20, 2019, 7:36pm UTC](https://discourse.julialang.org/t/keeping-modules-clean-when-including-files/32525/1 "2019-12-20T19:36:03Z")

</div>

Hi,  
I’m writing a module to test the code of a project I’m working on. I though of using multiple files containing the input data and then combine them to obtain all the test cases I need.  
To better explain what I want to do consider the following 3 files:

1. “a.jl”

```julia
a=61

```

1. “b.jl”

```julia
b=2

```

1. “Test.jl”

```julia
module Test
export @run
c = 10.0

macro run(f1, f2)
    code = quote
        include(@eval $f1)
        include(@eval $f2)
        d = 1.1
        a+b+c+d
    end
    return :($code)
end
end

```

The files a.jl and b.jl define the data (with variable names which are fixed), while Test.jl contains the module for testing. When I use this code I get the following output:

```julia
julia> include("Test.jl")
Main.Test

julia> Test.@run("a.jl", "b.jl")
74.1

julia> Test.a
61

julia> Test.b
2

julia> Test.c
10.0

julia> Test.d
ERROR: UndefVarError: d not defined

```

As expected the variables a and b are added to Test by the includes, while d is available only in the macro.  
What I would like to achieve is that after running the macro @run the module stays “clean” from the variables defined in the included files. For example, in the example above I would like a and b to be not define in the module Test after calling @run.  
Is this possible?  
Thanks  
Carlo

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [December 20, 2019, 10:17pm UTC](https://discourse.julialang.org/t/keeping-modules-clean-when-including-files/32525/2 "2019-12-20T22:17:32Z")

</div>

`include()` always works at global scope within the module. So if the file you are including contains something like `a = 1`, then no, there is no way to `include()` that file without it creating a global variable named `a`.

This is by design. `include()` is not meant to be used to paste in a bunch of code somewhere inside the body of a function, which is essentially what you’re asking it to do.

Relatedly, the macro isn’t necessary–it just obscures what is actually going on. We can achieve the same behavior with a function:

```julia
julia> module Test
       function run(file)
         @eval Test begin
           include($file)
           d = 1.1
           a + d
         end
       end
       end
WARNING: replacing module Test.
Main.Test

julia> Test.run("a.jl")
2.1

julia> Test.a
1

```

where `"a.jl"` just consists of the line `a = 1`. This has the same behavior and the same problem as your original code.

In my experience, the fundamental problem here is trying to store _data_ using _code_. If, instead, you store your _data_ as _data_, the problem goes away. For example, we could create a file `"a.json"` which looks like:

```julia
{
  "a": 1
}

```

and then write our analysis code like this:

```julia
julia> using JSON

julia> function run(file)
         data = JSON.parsefile(file)
         d = 2
         data["a"] + d
       end
run (generic function with 1 method)

julia> run("a.json")
3

```

suddenly all of the complexity goes away. No macros, or evals or includes are necessary, and no extraneous variables are created. Everything works exactly as intended.

Of course, there’s the minor inconvenience that you have to access `data["a"]`. You can trivially bind that to a local variable `a = data["a"]`, and you could even create a macro to make that eaiser. In my experience that’s almost never a significant problem. If your data has a huge list of variables and no structure at all, then that’s an indication that it’s worth spending some time to _make_ a structure to your data.

---

<div class="post-metadata">

### Author: ![csavorgn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csavorgn/32/9798_2.png) [@csavorgn](https://discourse.julialang.org/u/csavorgn)
#### Post date: [December 21, 2019, 5:11pm UTC](https://discourse.julialang.org/t/keeping-modules-clean-when-including-files/32525/3 "2019-12-21T17:11:44Z")

</div>

Thank you for the detailed answer. In my original post I didn’t mention it, but in the files I want to include I have also some Julia code. I’ll think if i can organize the test differently. In the meanwhile I just realized that if I include Test.jl after running using @run the module is redefined and therefore it does not contain the unwanted variables: not an elegant solution but if I don’t find anything else it works.
