module M
struct Config
...
end
const config = Ref{Config}()
f(arg1) = f(CONFIG[], arg1)
function f(config::Config, arg1)
#logic with config and arg
end
end
That way, you can bypass the default config when you need to without changing it for all calls.
It’s also worth noting that you could use ScopedValues introduced in 1.11 to make dynamic but const-global like variables instead of large config structs if you’re always unpacking anyway.
I think the Ref pattern originates in a time where Julia didn’t have typed globals. Nowadays, typed globals should behave (almost?) identical to that pattern.
Maybe its time I just put this on github, but for now I’ll continue with the pseudo-package. Based on the comments I tried:
module MyPackage
include("mysrc.jl")
# const CONFIG = Ref{Config}()
end
@with_kw struct Config
a :: Int64 = 0
[...]
end
function myfunc()
@unpack_Config CONFIG
[...]
end
const CONFIG = Config();
res = myfunc()
I get the error:
julia> res = myfunc()
nested task error: UndefVarError: `CONFIG` not defined in `MyPackage`
If I instead do:
module MyPackage
include("mysrc.jl")
const CONFIG :: Config = Config()
end
Then the values cannot be modified in a script:
julia> CONFIG.a = 10
ERROR: setfield!: immutable struct of type Config cannot be changed
julia> CONFIG = Config(a = 10)
WARNING: redefinition of constant Main.CONFIG. This may fail, cause incorrect answers, or produce other errors.
Thanks, it felt like I was using a workaround “trick” though.
I was wondering about why there isn’t a more elegant way (or more likely I missed it).
Preferences.jl may be a solution but even that requires an entire new file. I’m sure theres some history in github comments I don’t know how to find.