Best way to update parameter values in a temporary module

I am a Julia user mostly interested in numerical prototyping, where I have constant need to work with a large collection of custom functions that are related to each other, but far from being ready to define a package. I currently wrap the whole collection of codes in a temporary module in a .jl file in my search path to allow Revise detect any changes. That worked fine but pretty awkward.

Often times I need to quickly change certain values within the module while working in a REPL to test these changes on-spot. My question is how to do this more efficiently from REPL without constantly changing the source code. I could write a function like this to automatically go through a large number of param values and check the results in a loop.

module tempModule
...
... some_code_using_`param` ...
...
function change_param(param_new)
global param=param_new
... update_module ...
end
...
end #module

According to this thread, global variables wrapped in a function (or module, supposedly) should be efficient. However, I know that using global variables are generally discouraged.
Is there a better way of doing this without changing the source code?

You can eval into an existing module to redefine functions, but if you’re just trying to change a single value then using a Ref is pretty convenient:

julia> module MyModule
         const x = Ref(1.0)
         
         g(y) = y + x[]
       end
Main.MyModule

julia> MyModule.g(1)
2.0

julia> MyModule.x[] = 2
2

julia> MyModule.g(1)
3.0
1 Like

And here’s a version using eval to redefine a single function within the module:

julia> module MyModule
         x() = 1.0
         
         g(y) = y + x()
       end
Main.MyModule

julia> MyModule.g(1)
2.0

julia> @eval MyModule x() = 2.0
x (generic function with 1 method)

julia> MyModule.g(1)
3.0
1 Like

Mm, that thread isn’t particularly informative in this case. Your code as posted will absolutely have performance problems due to param being a non-const global variable. The fact that you access that global within a function is not helpful.

The Ref trick avoids the problem–you can safely do const x = Ref(1.0) and then mutate x later with x[] = 2.0. This is completely fine because const doesn’t stop you from mutating the value of x; it only promises that you will not assign the label x to some new value entirely.

However, according to the second benchmark case in the thread, Wrap the code in a function, the function f referring to the parameters outside its own scope seems to perform as well as if those parameters were const global variables? I imagine it to be similar if the parameters were wrapped within a module?