# Errors in creating a small, multi-file project with one module

**URL:** <https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324>\
**Category:** New to Julia\
**Tags:** question, modules\
**Created:** [January 26, 2024, 11:11pm UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324 "2024-01-26T23:11:31Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Spydercrawler](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spydercrawler/32/206565_2.png) [@Spydercrawler](https://discourse.julialang.org/u/Spydercrawler)\
**Post date:** [January 26, 2024, 11:11pm UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/1 "2024-01-26T23:11:31Z")

</div>

Hello!

I am a new Julia user, using v1.10, and am struggling a bit to fully understand how to get multiple code files to work together. Specifically, I am finding that editing files can throw errors, and my `using` statements do not always import necessary code. The documentation seems pretty confusing to me, and I haven’t found julia examples that use multiple files like this, so I thought I would ask for help here.

I have a filesystem with three files. The system looks like the following.

> Module1.jl  
> ObjectFolder  
> ⤷Object1.jl  
> RunnerFolder  
> ⤷Runner1.jl

Let’s go through each of the files now.  
**Object1.jl** is a file that simply contains a struct definition. Later, I might add some functions that use this, but for now I simply care about defining a new data type:

```julia
struct Object1
    variable1::Vector{Int64}
end

```

**Module1.jl** is a file containing a simple module definition. Currently, all it does is include Object1.jl:

```julia
module Module1
    include("ObjectFolder/Object1.jl");
end

```

Finally, **Runner1.jl** is intended on using the code in Module1 inside a coherent script. The concept is that all my helper code is in the module, and then my Runner actually uses the code:

```julia
using Module1

Alice = [1,2,3];
print(Alice);
Bob = Object1(Alice);
print(Bob)

```

For the purposes of this post, I have changed the name of the files, but the contents are correct. I have added the parent folder containing Module1.jl and every subfolder to the LOAD\_PATH so that it is recognized by the “using” statement correctly.

When I run this, I get the following error:

```julia
[1, 2, 3]ERROR: UndefVarError: `Object1` not defined
Stacktrace:
 [1] top-level scope
   @ FILEPATH\Runner1.jl:4

```

So, I know that the “using” statement does not throw an error, because Alice is successfully printed. However, the “Module1” module is not being imported by the `using` statement, as the error shows. That, or the module is not actually functioning as I would expect, and is not importing the struct code from Object1.jl.

I have a few questions, for anyone who would be willing to help me out here:

1. Why is the Object1.jl code not being imported by the module? Am I not understanding how modules are supposed to function?
2. How do I get two code files to work together like this? I am explicitly trying to avoid defining all of my code in one file, because I will soon have to create a project that has too much code to keep track of in one place.
3. Are there any “Best Practices” for organizing code in multiple files like this? How would you approach this problem?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [January 27, 2024, 12:16am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/2 "2024-01-27T00:16:05Z")

</div>

I think you are just missing the `export Object ` in your module, do make it accessible outside when using it.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 27, 2024, 12:22am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/3 "2024-01-27T00:22:58Z")

</div>

> [@Spydercrawler](#):
>
> Why is the [Object1.jl](https://juliahub.com/ui/Packages/Object1) code not being imported by the module? Am I not understanding how modules are supposed to function?

I haven’t tried reproducing the same file hierarchy to test everything, but most probably it does not work as it is because `Object1` is not exported by `Module1`. You have two possibilities:

- either add `export Object1` somewhere in `Module1` (either inside `Module1.jl` or in `ObjectFolder/Object1.jl`. This sets things up so that `using Module1` brings `Object1` into scope in the client code.
- second possibility: in the client code (`Runner.jl`), refer to `Object1` with a fully qualified name: `Module1.Object1`.

> [@Spydercrawler](#):
>
> How do I get two code files to work together like this? I am explicitly trying to avoid defining all of my code in one file, because I will soon have to create a project that has too much code to keep track of in one place.

I’d say you seem to have grasped how `include` works, and this is the correct tool to use here. If you have some code that could be put in the same file, but is too large, simply put part of it in another file, and `include()` that file in its place.

> [@Spydercrawler](#):
>
> Are there any “Best Practices” for organizing code in multiple files like this? How would you approach this problem?

I’d say you have it almost right, but the only missing part to follow “best practices” would be to put your “library code” inside a _package_. This is a bit stronger than a _module_, in that every package defines a top-level module, whereas not every module corresponds to a package. A package is an “atomic” piece of code in Julia, destined to be re-used elsewhere (in your case, in the `Runner` code).

The whole project could look like this:

```julia
MyProject
+- src
| +- MyProject.jl # defines a module, can include other code
| +- object1.jl
+- Project.toml # contains meta-data about the project
+- runner.jl # code living outside the module, but using it

```

You can initially create this directory structure (including the `Project.toml`) by running

```julia
julia> import Pkg
julia> Pkg.generate("MyProject")

```

Now you put your library code in `src/MyProject.jl`. If it gets too large you can `include()` from there other source files in the `src` subfolder.

Now the good part is this: instead of fiddling with `LOAD_PATH` in order to be able to use your code, all you need is to `activate` the project. Assuming you run julia from the directory where your project is defined:

- either use something like `import Pkg; Pkg.activate(".")` in an interactive session, or
- use an IDE such as VScode that does this for you automatically, or
- pass the `--project` command line option when you start julia. For example, to run your script non-interactively: `julia --project=. runner.jl`.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [January 27, 2024, 1:12am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/4 "2024-01-27T01:12:27Z")

</div>

> [@ffevotte](#):
>
> `julia> Pkg.generate("MyProject")`

I suggest using `PkgTemplates.generate()` instead. It’s more comprehensive, customizable and interactive.

> [@ffevotte](#):
>
> The whole project could look like this:
> 
> ```julia
> MyProject
> +- src
> | +- MyProject.jl # defines a module, can include other code
> | +- object1.jl
> +- Project.toml # contains meta-data about the project
> +- runner.jl # code living outside the module, but using it
> 
> ```

IMO it’d be better to put the runner.jl script outside the package directory.

> [@Spydercrawler](#):
>
> Are there any “Best Practices” for organizing code in multiple files like this? How would you approach this problem?

My rules are:

1. each source file in a package’s `src/` directory must start with `module FileName`
2. only use `include` in the top-level module

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [January 27, 2024, 1:43am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/5 "2024-01-27T01:43:37Z")

</div>

On the whole, I prefer the suggestions of @ffevotte

> [@nsajko](#):
>
> > [@ffevotte](#):
> >
> > `julia> Pkg.generate("MyProject")`
> 
> I suggest using `PkgTemplates.generate()` instead. It’s more comprehensive, customizable and interactive.

For a beginner in a case such as this, `Pkg.generate` is simpler and perfectly adequate.

> [@nsajko](#):
>
> > [@ffevotte](#):
> >
> > The whole project could look like this:
> > 
> > ```julia-auto
> > MyProject
> > +- src
> > | +- MyProject.jl # defines a module, can include other code
> > | +- object1.jl
> > +- Project.toml # contains meta-data about the project
> > +- runner.jl # code living outside the module, but using it
> > 
> > ```
> 
> IMO it’d be better to put the runner.jl script outside the package directory.

@ffevotte s suggestion is simpler and I use it myself sometimes, especially if it is an informal package that is purely for personal purposes and still under development.

> [@nsajko](#):
>
> My rules are:
> 
> 1. each source file in a package’s `src/` directory must start with `module FileName`
> 2. only use `include` in the top-level module

In my opinion, your rule no. 1 is too restrictive, I feel that @Spydercrawler s way of using include is sensible and is what I use as well.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [January 27, 2024, 1:46am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/6 "2024-01-27T01:46:34Z")

</div>

> [@GHTaarn](#):
>
> For a beginner in a case such as this, `Pkg.generate` is simpler and perfectly adequate.

IMO there’s no reason to use `Pkg.generate`, and I would especially recommend PkgTemplates.jl to a beginner.

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [January 27, 2024, 1:49am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/7 "2024-01-27T01:49:49Z")

</div>

Well, our opinions differ

---

<div class="post-metadata">

**Author:** ![Spydercrawler](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spydercrawler/32/206565_2.png) [@Spydercrawler](https://discourse.julialang.org/u/Spydercrawler)\
**Post date:** [January 27, 2024, 5:30am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/8 "2024-01-27T05:30:47Z")

</div>

I would like to let you know that this is an incredible response, and completely answers my questions.

Most of the time, I am quite scared to go onto any type of programming forum, because people can sometimes be quite snarky, especially towards newcomers. This answer completely blew all of my expectations out of the water, so thank you very much.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [January 27, 2024, 6:52am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/9 "2024-01-27T06:52:36Z")

</div>

I have writtem a tutorial on modules, packages and, eventually, how to document, test and register a package:

> **[11 - Developing Julia packages](https://syl1.gitbook.io/julia-language-a-concise-tutorial/language-core/11-developing-julia-packages)**

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 27, 2024, 9:18am UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/10 "2024-01-27T09:18:44Z")

</div>

> [@Spydercrawler](#):
>
> I would like to let you know that this is an incredible response, and completely answers my questions.

Thanks! I think you’ll find that there are lots of “incredible responses” here. In any case, I’ve personally never found a community as talented as the people you’ll see here if you stick around, yet welcoming at the same time. Welcome!

  

Regarding some of the other comments, I could perhaps have made a better job of separating what-you-should-do-because-that’s-pretty-much-the-one-recommended-way from the objectives-everyone-agrees-you-should-strive-for-but-there-are-multiple-ways-to-get-there.

I’d say everybody will agree that it’s a good idea to separate “library code” that _defines/declares_ functions/types/etc from “scripts” that actually _run/execute_ code. You had that one completely right!

- I think there’s a strong consensus that library code should go into packages. There are however several tools allowing one to build a package; which one to use will depend on personal preferences, the size of the project, the type of QA you’re aiming for, etc.

- I also think everybody will agree that “scripts” should live outside the packages sources (i.e. outside the `src` directory). Exactly where will depend on a broader context and/or personal taste, though. Scripts can actually live pretty much everywhere; you just have to remember to activate the right project environment when you run them.

---

<div class="post-metadata">

**Author:** ![moble](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moble/32/23535_2.png) [@moble](https://discourse.julialang.org/u/moble)\
**Post date:** [January 29, 2024, 4:33pm UTC](https://discourse.julialang.org/t/errors-in-creating-a-small-multi-file-project-with-one-module/109324/11 "2024-01-29T16:33:09Z")

</div>

Another standard piece of advice for developing packages is to use [Revise.jl](https://timholy.github.io/Revise.jl/stable/). I think most people add it to their base project (the one you get when you run `julia` without a `--project` argument), so you don’t have to add it to every project that you want to use it in. Then, just run `using Revise` before loading your package, and any changes you make to the package after that will be automatically loaded into your running session.

I believe VS Code with the julia extension does this automatically, so a superseding piece of advice might just be to use VS Code.
