Superconf
See Superconf::Option for the high-level overview. This file holds the
process-wide singleton registry and its load/dump machinery.
Framework-agnostic: a terminal library and the app using it can both register into the same registry, so every option appears in one combined, dumpable list.
Constants
Parser for a String?-valued option: the built-in casts cover String
but not the String | Nil union, so such options pass this proc
explicitly. A present value is taken verbatim.
The CLI flags load_args always registers itself. An option that claimed
one of these would have its handler overwritten by the built-in (handlers
are keyed by flag string), so it must be rejected up front — see
ensure_cli_free.
Class methods
Look up an option, raising Superconf::Error if it isn't registered.
Application name used by default_config_path (e.g. ~/.config/<name>/...).
Opt in to external configuration sources, in precedence order (lowest to
highest): a config file, then environment variables, then command-line
options. If file is given it is loaded; otherwise default_config_path is
loaded when it exists. Pass file: "" to skip file loading entirely.
Whether option key carries a non-default value — i.e. some source (config file, env, CLI, runtime) actually configured it. A value equal to the default is treated as unconfigured, so library code can safely use this as "should the configured value override a programmatic one".
The default per-user config path: $XDG_CONFIG_HOME/<app_name>/config.yml,
or ~/.config/<app_name>/config.yml when $XDG_CONFIG_HOME is unset.
Dump the full configuration to io in format. :yaml/:json produce
valid, re-loadable config files; :env is a sourceable shell script;
:pretty is a human table that also shows each value's source; :report
is rich JSON with full per-option metadata.
The environment-variable name for opt: its explicit env: if given, else
env_prefix + the derived suffix. Computed lazily so a prefix set after
registration still applies.
Prefix prepended to derived environment-variable names (options that did
not pass an explicit env:). The final application typically sets this once
to brand the whole config space, e.g. Superconf.env_prefix = "CRYSTERM_".
It is applied lazily, so it affects options registered before it is set too.
Prefix prepended to derived environment-variable names (options that did
not pass an explicit env:). The final application typically sets this once
to brand the whole config space, e.g. Superconf.env_prefix = "CRYSTERM_".
It is applied lazily, so it affects options registered before it is set too.
Dynamic, string-keyed read. Prefer the typed accessor (Superconf.<name>)
in normal code; this is for keys known only at runtime. Raises if the key
is unknown or type doesn't match how the option was registered.
Apply command-line options (at Source::CommandLine). Recognized flags are
matched against the registry; two built-ins are always available:
--config FILE— additionally load a YAML/JSON config file--dump-config [FMT]— dump configuration (yaml|json|env|pretty|report, default yaml) and exit
Unknown options are ignored so an app's own parsing is left intact. By
default the real argv is consumed (recognized flags removed); pass
consume: false to parse a copy non-destructively. Returns self.
Apply matching environment variables (at Source::Env). No-op for any
option whose env var is unset. Returns self for chaining.
Load a config file by path. JSON is valid YAML, so the same parser handles
both .yml and .json.
Load a YAML document (string or IO) at Source::ConfigFile. Accepts nested
group mappings (screen: {resize_interval: 0.5}) and/or flat dotted keys
(screen.resize_interval: 0.5). Unknown keys are ignored.
Register a new option and return a typed handle whose #value you can read
directly. The value type T is inferred from default.
cli and group are derived from key unless given; env defaults to a
lazily-derived name (see env_name). For value types beyond the built-ins
(Bool/Int*/Float64/String/Char/Time::Span/Enum) pass a parse
proc. validate is an optional predicate run against every effective value
(and against default); a false result raises Superconf::Error.
Registering a key that already exists raises — keys are unique.
Register an alias: a second name (alias_key) for an already-registered option (target_key). The alias shares the target's value, type, default, parsing and validation, and gets its own config key, env var and CLI flag (derived from alias_key unless overridden). Reading or writing either name affects the one shared value.
Use it, like set_default, when an app wants to promote a library's option
under its own name. The library's name keeps working; the app's name becomes
an equal surface beside it:
module Superconf
option "screen.resize_interval", 0.2.seconds # declared by a library
end
Superconf.register_alias "myapp.refresh", "screen.resize_interval"
Superconf.set "myapp.refresh", 1.second # writes the shared value
Superconf.get("screen.resize_interval", Time::Span) # => 1.second
# MYAPP_REFRESH / --myapp-refresh / `myapp.refresh:` now work too
Aliasing an alias is allowed and resolves to the same underlying option.
Registering an alias_key that already exists raises; an unknown
target_key raises. Call it early (before configure!/load_*). Returns
the alias handle.
Dynamic, string-keyed write at Source::Runtime (always wins). Raises on
type mismatch. Prefer Superconf.<name> = ... in normal code.
Change the default of an already-registered option. Unlike set (which
writes at Source::Runtime and wins over everything), this writes at
Source::Default precedence, so a config file / env var / CLI flag / runtime
assignment still overrides it. Use it when an app wants a different baseline
than a library's registered default — e.g. crysterm choosing a different
tput.read_timeout — while keeping it user-overridable.
Also updates the recorded default (so dumps and default_string stay
consistent). If a higher-precedence source already set the value, the
effective value is left untouched; only the recorded default changes. Call
it early (before configure!/load_*).
Macros
Declare a typed option: registers it (so it gets an env var, CLI flag,
config key, source tracking, and a line in every dump) and defines
statically-typed accessors Superconf.<name> / Superconf.<name>=, where
<name> is the key with dots turned into underscores.
Ergonomic front door — Superconf.screen_resize_interval returns the value
directly, with no string key or type argument, reading a cached handle (no
hash lookup). Libraries and apps use it by reopening the module:
module Superconf
option "myapp.refresh", 1.second, description: "Refresh interval"
end
Superconf.myapp_refresh # => Time::Span (typed)
Superconf.myapp_refresh = 5.seconds
Accepts the same options as register, including parse: and validate:.
Declare a typed alias of target: registers an alias named key (see
register_alias) and defines the typed accessors Superconf.<name> /
Superconf.<name>= of value type type, where <name> is key with dots
turned into underscores. The alias counterpart of option — the ergonomic,
typed way for an app to promote a lower-level option:
module Superconf
option_alias "myapp.refresh", "screen.resize_interval", Time::Span
end
Superconf.myapp_refresh = 1.second # writes the shared value
Superconf.myapp_refresh # => Time::Span
type is the target option's value type. The target must already be
registered when this runs (declare the library's option first).