1 Quickstart via #lang envy
To get started, create a module to manage your application’s environment variables (e.g. environment.rkt).
#lang envy
To specify which environment variables your application depends on, specify each variable’s name on a separate line:
#lang envy some-environment-variable another-environment-variable
Each line of your environment manifest will produce a variable with the given name bound to the value of the equivalent environment variable. The name of the environment variable will be generated from the name of the Racket variable by converting the identifier to ALL_CAPS, converting dashes to underscores, and stripping question marks. In the above example, Envy would fetch the values for SOME_ENVIRONMENT_VARIABLE and ANOTHER_ENVIRONMENT_VARIABLE.
When the module runs, the values for the specified variables will be loaded, but it’s possible that the variables don’t actually exist in the environment. In this case, an error will be thrown.
#lang envy some-environment-variable
> envy: The required environment variable
"SOME_ENVIRONMENT_VARIABLE" is not defined.
If the environment variable does exist, its value will be stored in the binding.
#lang envy some-environment-variable another-environment-variable
> some-environment-variable - : String
"some value"
To use the values of these environment variables in another module, just require the module, optionally with a prefix.
1.1 Specifying types
All environment variables are natively strings, but it is extremely common to store other kinds of configuration data, such as booleans and numbers. Envy permits specifying a type with each variable, and it will automatically parse the value to match the specified type.
For example, given the following environment:
HOST=racket-lang.org |
PARALLEL=true |
THREADS=42 |
...one could use the following environment definition:
host : String parallel? : Boolean threads : Positive-Integer
> host - : String
"racket-lang.org"
> parallel? - : Boolean
#t
> threads - : Integer [more precisely: Positive-Integer]
42
Note that the values are defined with the specified types, useful for Typed Racket users. Also, since String is the default type, including it is not strictly necessary.
1.2 Providing defaults
Sometimes, configuration variables may be optional, in which case it is useful to provide a default value instead of raising an error upon an undefined variable. This can be done with the #:default option.
optional-value #:default #f
> optional-value - : (U False String)
#f
Note that the type is still properly preserved for Typed Racket users, so if the default value’s type is different from the type of the environment variable, the resulting type will be a union.
1.3 Using explicit environment variable names
Sometimes it is desired to define a variable with a different name from the name used in the environment. This can be done with the #:name option.
custom-name #:name "ENVIRONMENT_NAME"