# PSA: Use modules for dirty work preparing scripts, debugging, etc

**URL:** <https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068>\
**Category:** General Usage\
**Tags:** modules, good-practices\
**Created:** [September 5, 2024, 8:43am UTC](https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068 "2024-09-05T08:43:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [September 5, 2024, 8:43am UTC](https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068/1 "2024-09-05T08:43:25Z")

</div>

Let’s say I’m preparing a script, e.g. to analyze data in a project. The recommended practice is to put as much code as possible in functions, keeping the global scope clean. But while I’m designing those functions (or debugging them after they have been written) I need to see what’s happening step by step, with some example data. Of course, there are good tools for that - Debugger.jl (or VS Code’s built in debugger), Infiltrator.jl, etc. But they need some setup to be used, and sometimes one feels urged to do quick-and-dirty copy-pasting on the REPL, messing up the global scope.

Another conflict with Julia’s good practices: “if you need global variables, make them `const`”. OK, but when I’m in the process of writing the script, I often find out that the values of such constants should be modified, and I have to restart the session to redefine them in a safe manner.

Both issues, and others similar, can be addressed by doing that prototyping or debugging work in a module different from `Main`, so that once you have finished the work (or have messed too much with its global scope), you can get rid of it and restart with another module, without restarting the whole Julia session. This comes for free if you are developing a package, since packages have their own modules (with the bonus provided by Revise.jl, if you use it), but this is also easy to do outside them - in the REPL since Julia 1.9, and in VS Code for a much longer time, see:

> [@Change "current working module" from REPL](https://discourse.julialang.org/t/change-current-working-module-from-repl/53166):
>
> In package development, I often find myself needing to bring lots of things into scope, so I can run bits and pieces as if my package were running them. Something like julia\> using Foo # or some package I'm developing julia\> using Foo: f, g, h, j julia\> using Bar # a dependency of `Foo` etc. It’s a lot of typing, and it’s very error prone. It would be a lot easier if we had a way to change modules from the REPL. Is this possible? Or maybe there’s an easy way to automate what I’m currently doi…

I know that this is not news, but this feature is often presented as something to facilitate the development of packages, and I’m sure that there are many users who do not consider themselves “package developers”, who can also take advantage of this, so perhaps they might benefit from this “personal self-advice”.

My workflow to do such kind of things is:

1. After starting the REPL, create a playground module, e.g. `module MyPlayground end`.
2. Move the REPL to that module, typing `MyPlayground` and hitting Alt+m. (In VS Code, also change the current module in the bottom bar.)
3. `include` the script with the code written so far (loading packages, defining functions, constants…). In the first iteration, this might be empty.
4. Work on the script as usual, messing up with the global scope if necessary.
5. When I feel like cleaning the global scope, return to `Main` (same procedure as #2).
6. Go to #1 with a new module, e.g. `MyPlayground2`, and repeat.

From another perspective, this workflow is more or less equivalent to the process of “cleaning the workspace” or “deleting everything” that some people feel missing in Julia, except that it does not really delete anything, just puts it in a module that you can leave out and ignore later. Therefore, after various iterations the Julia session may be consuming a lot of memory, and restarting may be inevitable, although that depends on the computer and how big the data are.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [September 5, 2024, 2:09pm UTC](https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068/2 "2024-09-05T14:09:24Z")

</div>

This seems like a good idea. It also seems like it’d be good to take your old module, iterate through all the globals and set them to `nothing` and run a GC. This would avoid all the memory accumulation issues. I’m not sure how to do this though.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [September 5, 2024, 3:30pm UTC](https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068/3 "2024-09-05T15:30:16Z")

</div>

In simple situations, it might be possible to go through the whole namespace of the module with `names`, and set the referred objects to `nothing`, but this should only be done with non-constant objects (i.e. simple variables) that have not been annotated with a type incompatible with `Nothing`. For instance:

```julia
function wipeout(module)
    for x in names(module, all=true)
        if !isconst(module, x) && Nothing <: Core.get_binding_type(module, x)
            setproperty!(module, x, nothing)
        end
    end
end

```

Nevertheless, modules can contain virtually any kind of thing, so I guess that there may be cases where that naïve attempt fails.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 6, 2024, 12:01am UTC](https://discourse.julialang.org/t/psa-use-modules-for-dirty-work-preparing-scripts-debugging-etc/119068/4 "2024-09-06T00:01:55Z")

</div>

I use a similar workflow, which I think is probably better.

```julia
module MyModule

function fun1()
    return 1
end

function main()
@eval begin 
    x = fun1()
end

```

Do `using Revise`, then do `using MyModule` along with `Alt+m` method of making the REPL refer to `MyModule`. But this way `main` is tracked by Revise.

The downside is that the folder structure has too look like a real julia package, like via `] develop`. But you can have multiple sub-modules that are really just `main() ... end` and switch the REPL between them if you want.

It’s a little messy… but it’s a workflow for experimentation. Having a real folder structure is helpful if you decide you _do_ want to make something a real module as well.
