Preferences.jl

repository·master·Indexed 40 days ago

https://github.com/juliapackaging/preferences.jl

A Julia package providing a mechanism for storing and retrieving configuration settings in TOML files. It supports runtime configuration and compile-time code generation optimizations for Julia v1.6+, featuring macros such as @load_preference, @set_preferences!, @has_preference, and @delete_preferences! to manage local and exported preferences.

Tokens
1.1K
Snippets
3
Records
4
Agent score
50%

What's inside Preferences.jl

  1. Overview of Preferences.jl

    master

    Preferences.jl allows Julia packages to store configuration settings in persistent TOML files. These settings can be used at both run time and compile time (in Julia v1.6+).

    Storage Mechanisms

    • Local Preferences (Default): Stored in a (Julia)LocalPreferences.toml file next to the currently active project. This is ideal for user-specific overrides and should be added to .gitignore.
    • Exported Preferences: If you set export_prefs=true when calling @set_preferences!(), the settings are stored in the [preferences] section of the (Julia)Project.toml file. This is intended for shared project settings that should be distributed with the package.

    Inheritance and Overriding

    Preferences follow the Julia environment stack. Preferences set in higher-level environments (like a global depot) act as defaults but can be overridden by more proximal entries in the LOAD_PATH, such as the currently active project.

  2. How compile-time preferences work

    master

    When a preference is accessed during compilation (e.g., inside a function that is being specialized or used with @static if), it is automatically marked as a compile-time preference.

    Recompilation

    Changing a compile-time preference triggers the Julia compiler to recompile any cached precompilation .ji files for that module. Because this affects code generation, it is recommended to advise users to restart their Julia session after changing such a preference.

    Opting out of invalidation

    If you want to prevent a preference from triggering recompilation, you can use force_compiletime_default=true within load_preference(). This ensures the function always returns the default value during precompilation instead of the actual stored preference value.

    # Example of using a preference to influence code generation at compile-time
    const backend = @load_preference("backend", "OpenCL")
    
    function do_computation()
        @static if backend == "OpenCL"
            return "OpenCL logic"
        elseif backend == "CUDA"
            return "CUDA logic"
        end
    end
  3. Conditionally load Preferences for backward compatibility

    master

    Since Preferences.jl requires Julia v1.6+ to function, you can use @static if blocks to provide fallback behavior for older Julia versions.

    Note: You cannot merge the using Preferences statement into the same @static if block used for loading preferences; the package loading must occur in its own block.

    @static if VERSION >= v"1.6"
        using Preferences
    end
    
    @static if VERSION >= v"1.6"
        preference = @load_preference("preference", "default")
    else
        preference = "default"
    end
  4. Use Preferences.jl API macros

    master

    The package provides four primary macros for managing package preferences:

    • @load_preference(key, default = nothing): Retrieves the value for key. Returns default if the key is not found.
    • @set_preferences!(pairs...; export_prefs=false): Sets one or more preferences as key-value pairs. Use export_prefs=true to save them to Project.toml instead of LocalPreferences.toml.
    • @has_preference(key): Returns true if the preference exists, otherwise false.
    • @delete_preferences!(keys...): Removes one or more preferences by their keys.
    # Setting preferences
    @set_preferences!("backend" => "CUDA", "verbose" => true)
    
    # Loading a preference with a default
    backend = @load_preference("backend", "OpenCL")
    
    # Checking for existence
    if @has_preference("backend")
        println("Backend is set")
    end
    
    # Deleting preferences
    @delete_preferences!("verbose")