Stream: helpdesk (published)

Topic: Parameters for nested functions


view this post on Zulip Moorits Muru (Sep 12 2024 at 13:31):

I am writing a module for my personal use. I have some utility functions where I usually only need to change one or a few arguments and others have default values. But sometimes I would like to be able to use something other than the default values. I guess this is a suitable job for a config, but I am not sure how to do that in Julia. I guess I could use some global or const values, but I am not sure if this is a good approach.

For example, I have a function that outputs a path of a file based on some inputs. One of the inputs is also the base path of the data directory, which I would like to just give a default value.

const base_path = "/drive/data"
function get_sim_path(simID)
    joinpath(base_path, "simulation_$(simID)_raw.csv")
end

or

function get_sim_path(simID, base_path = "/drive/data")
    joinpath(base_path, "simulation_$(simID)_raw.csv")
end

This function is used by another function, such as

function extract_IDs(simID)
    path = get_sim_path(simID)
    ....
    IDs
end

In reality these function take more arguments and are sometimes even more nested. I would like to not have to include all the arguments all the way up. What are the common solutions for this? I don't expect to need to change these values interactively. These would be read once, run once kinda thing.

view this post on Zulip Gunnar Farnebäck (Sep 12 2024 at 14:32):

I did this in my current job project:

using Preferences
export set_test_data_dir, get_test_data_dir

# This gets stored in a LocalPreferences.toml file, which is .gitignored.
function set_test_data_dir(path)
    @set_preferences!("test_data_dir" => path)
end

function get_test_data_dir()
    return @load_preference("test_data_dir",
                            joinpath(dirname(@__DIR__), "test", "data"))
end

view this post on Zulip DrChainsaw (Sep 13 2024 at 06:03):

A low tech solution is to just slurp and splat keyword arguments. Once you have added it to the higher level functions you can just add keyword arguments to the lower ones and they will just propagate.

foo_top(x; kws...) = foo_mid(x, kws...)

function foo_mid(x, mid_kw=3, kws...)
#use mid_kw for something
foo_bottom(x, kws...)
end

foo_bottom(x, kw1=1, kw2="aa") = ...

view this post on Zulip Moorits Muru (Sep 13 2024 at 21:15):

Thanks for showing how to do it with kwargs, but I think that would be a bit too much noise. I think I will use Preferences.jl. I found now that it is also the recommended package in the Pkg.jl docs.


Last updated: Nov 06 2024 at 04:40 UTC