# Best way to include local module (with struct) in Pluto

**URL:** https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044
**Category:** New to Julia
**Tags:** pluto
**Created:** [September 20, 2023, 1:00am UTC](https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044 "2023-09-20T01:00:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![luke-pikaart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luke-pikaart/32/29361_2.png) [@luke-pikaart](https://discourse.julialang.org/u/luke-pikaart)
#### Post date: [September 20, 2023, 1:00am UTC](https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044/1 "2023-09-20T01:00:34Z")

</div>

I am trying use Pluto with a local module.

I have a module like:

### foo.jl

```julia-auto
module foo

export foobar

    struct foobar
        A:Int
    end
end 

```

I think the recommended way to do this is:

### notebook1.jl

```julia-auto
include("foo.jl")
using .foo

```

However the issue here is that the my struct is only exported to the cell where I did `using .foo`. I still have to do `foo.foobar` to access the struct in a new Pluto cell.

So I have to do an import to manually import `foo` to the scope of the whole notebook.

### notebook2.jl

```julia-auto
include("foo.jl")
using .foo
import .foo: foobar

```

This is fine for one struct but in reality I have a module with a bunch of stuff to import and I don’t want the added overhead of explicitly importing.

I have looked all around and found various recommendations on how to accomplish this. Fonsp had the idea of the `ingredients` function to sort of extend the import function to work better with Pluto reactivity.

[github.com/fonsp/Pluto.jl](https://github.com/fonsp/Pluto.jl/issues/115#issuecomment-661722426)

[https://github.com/fonsp/Pluto.jl/issues/115#issuecomment-661722426](https://github.com/fonsp/Pluto.jl/issues/115#issuecomment-661722426)

[![karlwessel](https://global.discourse-cdn.com/julialang/original/3X/e/7/e750a004fdbb4a2bbb64e96a97fde5f952632eb9.png) karlwessel](https://github.com/karlwessel)

reactivity

It currently is not possible to reevaluate a cell that includes a file which def[…](https://discourse.julialang.org/t/how-to-include-local-module-with-struct-into-notebook-scope/103871)

### notebook3.jl

```julia-auto
function ingredients(path::String)
	# this is from the Julia source code (evalfile in base/loading.jl)
	# but with the modification that it returns the module instead of the last object
	name = Symbol(basename(path))
	m = Module(name)
	Core.eval(m,
        Expr(:toplevel,
             :(eval(x) = $(Expr(:core, :eval))($name, x)),
             :(include(x) = $(Expr(:top, :include))($name, x)),
             :(include(mapexpr::Function, x) = $(Expr(:top, :include))(mapexpr, $name, x)),
             :(include($path))))
	m
end

foo = ingredients("foo.jl")

import .foo: foobar

```

This gives warning `could not import foo.jl.foobar into workspace

I think the exact syntax for importing local modules in julia in general has changed: (`include, using, import, .using, etc.`) since that discussion and I’m wondering about what is the current best practice.

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [September 20, 2023, 6:20am UTC](https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044/2 "2023-09-20T06:20:17Z")

</div>

This is certainly not the _best_ way, but it might suit your needs to add the location of the local module(s) to the `LOAD_PATH`. It’s basically faking the presence of a package in the given folder, which also works with single files, as long as the file name matches the module name (as described here [Code Loading · The Julia Language](https://docs.julialang.org/en/v1/manual/code-loading/#Package-directories) ).

The limitations I can think of right now are (basically the same as for any package)

- only one module per file/folder possible (nesting and re-exporting would work though)
- the file/folder name must match the module name
- the file/folder name should not match the name of an existing package in one of your registries or other load path locations (otherwise probably the wrong package gets used)

Here’s an example notebook that sets up and uses the local module (note that the display order is a bit weird… first is the struct definition, then saving to file, pushing to `LOAD_PATH`, then using):

```julia
### A Pluto.jl notebook ###
# v0.19.27

using Markdown
using InteractiveUtils

# ╔═╡ 688fef7a-3456-490b-82f8-029b77d0910c
push!(LOAD_PATH, pwd());

# ╔═╡ 84628da7-d690-4e13-8bc2-358c86afc711
using FooModule

# ╔═╡ 77631f94-577a-11ee-0b11-3be3c11e936b
structDef = """
module FooModule

export A

struct A
    i::Int
end

end
"""

# ╔═╡ 567b7c95-045f-42f3-87f2-920f86a8cdcc
write("FooModule.jl", structDef)

# ╔═╡ 2d80e649-4a0a-42f5-b70d-86fb298d1177
A(1)

# ╔═╡ Cell order:
# ╠═77631f94-577a-11ee-0b11-3be3c11e936b
# ╠═567b7c95-045f-42f3-87f2-920f86a8cdcc
# ╠═688fef7a-3456-490b-82f8-029b77d0910c
# ╠═84628da7-d690-4e13-8bc2-358c86afc711
# ╠═2d80e649-4a0a-42f5-b70d-86fb298d1177

```

EDIT: At least when playing around a little bit right now it seems to work fine. It also works to modify certain things in the module if we do `using Revise` is in the notebook.

---

<div class="post-metadata">

### Author: ![luke-pikaart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/luke-pikaart/32/29361_2.png) [@luke-pikaart](https://discourse.julialang.org/u/luke-pikaart)
#### Post date: [September 20, 2023, 12:14pm UTC](https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044/3 "2023-09-20T12:14:04Z")

</div>

Thanks, yeah that’s certainly a better way than I’ve found!

I had played with the load path a bit but “tricking it” with `pwd()` is clever. My use case is a notebook template that is used on different machines so I don’t want it to be a headache to import my base library every time someone uses it.

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [September 20, 2023, 12:25pm UTC](https://discourse.julialang.org/t/best-way-to-include-local-module-with-struct-in-pluto/104044/4 "2023-09-20T12:25:01Z")

</div>

Using the current directory seemed to be a good option, but I didn’t really think about it – at least Pluto notebooks are supposed to be self-contained and this felt like the next best thing 😅

I don’t know how you are distributing your base library to the machines/users, but if you have some sort of shared git server, maybe [`LocalRegistry.jl`](https://github.com/GunnarFarneback/LocalRegistry.jl) might be useful. Turning your library into a package has a bit of an overhead of course (setting up the local registry and, optionally, versioning the library), but in my case this setup cost was well worth it. Being able to just do a quick `pkg> add XYZ` and `using XYZ` anywhere within my network is pretty convenient.
