I can't quite understand difference between __init__
function and regular code written in module.
So, the problem is the following: I want to store some configuration parameters in a toml file, somewhere in a file system, and I want to read it during using
step. Where should I put initialization steps?
Version №1
module Foo
using TOML
const OPTIONS = Ref(0)
OPTIONS[] = TOML.parsefile("/config.toml")["var"]
end #module
or Version №2
module Foo
using TOML
const OPTIONS = Ref(0)
function __init__()
OPTIONS[] = TOML.parsefile("/config.toml")["var"]
return
end
end #module
Which one is a correct way of initializing variables?
And second question, is there any common Julia path, where I can keep this configuration file? I can do it in ~/.config/...
but I would prefer something more system independent.
Idk if there's a julia version of appdirs but I think that's the platform-agnostic application-agnostic answer to "which directory". Julia itself should use the XDG dirs too but currently doesn't.
The first will run when precompiling the package, the second when using
the package.
Andrey Oskin said:
And second question, is there any common Julia path, where I can keep this configuration file? I can do it in
~/.config/...
but I would prefer something more system independent.
Maybe have a look at https://github.com/JuliaPackaging/Preferences.jl
Thank you, so I suppose I need second, if I want to change settings between runs.
Between restarts, yes.
Thank you.
I do not quite get the idea of Preferences.jl. It can store preferences in LocalPreferences.toml
file of the package. But packages usually have path ~/.julia/packages/Foo/<some random token>/...
where random token is different between package versions. So what, each time I get a new version of the file, my LocalPreferences will be forgotten? It doesn't look convinient.
No that is not how it works, the LocalPreferences.toml
file is stored in your current project, for example:
$ ls
LocalPreferences.toml Manifest.toml Project.toml
$ cat Project.toml
[deps]
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
$ cat LocalPreferences.toml
[Example]
foo = "bar"
And global in Project.toml
of the package?
Yeah, it's not what I really want. I am always running julia with julia --project=.
so each time I have isolated environment.
It is exactly what you want, if you run julia --project=.
it will pick up preferences from the LocalPreferences.toml
file next to your Project.toml
.
But thank you, this package gave me few good ideas.
I guess in my case, I can do the same as thing as PyCall
:
const prefsfile = joinpath(first(DEPOT_PATH), "prefs", "Foo.toml")
mkpath(dirname(prefsfile))
PyCall.jl is moving to Preferences.jl too (https://github.com/JuliaPy/PyCall.jl/pull/945). I don't understand why Preferences.jl is not exactly what you want?
Guess we are both do not understand each other (and I do not understand Preferences.jl). Thank you for your patience, let me explain what I want in more details.
Suppose that I have package Foo, which can do some calculations and it produces some output for these calculations. It can be long description and it can be short description. So, I have to choose which type of description is default, but I do not want to set it in code, I want to make it optional.
My idea is the following: I can create system wide config file, where I can set output = compact
or output = long
.
For example I set this config file to output = compact
Now, I can go to directory 1 and run
julia --project=.
using Foo: Bar
x = Bar()
calc(x)
# Compact output
I can go to directory 2 and run
julia --project=. # it is new Project.toml and everything else
using Foo: Bar
x = Bar()
calc(x)
# Compact output, since I still use system wide preferences
If I change settings to output = long
then in each directory I run the same code, I'll see long output, because that's what I want. I kind of changes my desire for default behaviour.
Now, if I get it right, then Preferences.jl do something different. It allows me to set my settings in each directory individually, but if I am not doing it, then it uses default value from the package. I.e. each time I should do
cd dir3
julia --project=.
setpreferences(output=compact)
otherwise I get package default, not my default.
Hope it makes it more clear.
But may be I misunderstood general idea of Preferences.jl
Okay, I believe you can have global preferences with Preferences.jl too.
Andrey Oskin has marked this topic as resolved.
You can have preferences stored in your default environments Project.toml or a LocalPreferences.toml at the same location. The only drawback is that the package for which you want to record preferences has to be added to that environment.
So
using Preferences
using Example
set_preferences!(Example, "foo" => "bar")
stores it in ~/.julia/environments/v1.7/LocalPreferences.toml.
This can then be loaded using load_preference(Example, "foo")
which will traverse the LOAD_PATH to look for stored preferences.
It will read from ~/.julia/environments/v1.7/LocalPreferences.toml
even when I start Julia with --project=.
flag? It's going hierarchically? If it can't find local preferences in current directory it will read from global? If yes, it can make this approach more interesting (of course min 1.6 is still a huge drawback)
I guess I should just try it and see how it goes.
Yes, that should work. Since Julia versions < 1.6 are not supported versions anymore I don't think it is a drawback really.
Last updated: Nov 06 2024 at 04:40 UTC