module

ENV

ENV is a hash-like accessor for environment variables.

Example

Assuming the following example is invoked with the HOST=localhost and PORT=5000 environment variables:

p ENV["HOST"]                       # => "localhost"
p ENV["PORT"].to_i                  # => 5000
p ENV.fetch("TLS_PORT", "443").to_i # => 443

NOTE: All keys and values are strings. You must take care to cast other types at runtime, e.g. integer port numbers.

Safety

Modifying the environment in single-threaded programs is safe. Modifying the environment is also always safe on Windows.

Modifying the environment in multi-threaded programs on other targets is always unsafe, and can cause a mere read to segfault! At best, memory will be leaked every time the environment is modified.

The problem is that POSIX systems don't guarantee a thread safe implementation of the getenv, setenv and putenv libc functions. Any thread that gets an environment variable while another thread sets an environment variable may segfault. The Crystal runtime implementation of ENV itself is protected by a readers-writer lock, but we can't protect against external libraries, including libc calls made by the stdlib, to call getenv internally without holding the read lock while a crystal fiber with the write lock calls setenv.

The only safe solution is to consider ENV to be immutable, and to never call ENV.[]=, ENV.delete or ENV.clear in your programs. If you really need to, you must make sure that no other thread has been started (beware of libraries that may start threads without your knowledge).

NOTE: Passing environment variables to a child process should use the env arg of Process.run and Process.new.

Constants

DEFAULT_SECRETS_PATH = "/run/secrets"

Class methods

accessed(static_only) : Array(String)

DEPRECATED Static resolution no longer supported

Source
accessed

Returns the set of all environment variables or secrets that have been accessed by the program.

Source
each

Iterates over all KEY=VALUE pairs of environment variables, yielding both the key and value.

ENV.each do |key, value|
  puts "#{key} => #{value}"
end
Source
fetch(key : String, &block : String -> String | Nil)

Retrieves a value corresponding to a given key. The value will be retrieved from (in order of priorities): system env vars, available secrets files or the return value of the block.

This override the default ENV module behaviour to support reading of secrets injected to an environment from docker-compose, kubernetes and other orchestration tools.

Source
fetch_secret(key : String, &block : String -> String | Nil)

Retrieves a value corresponding to the given key. Return the value of the block if the key does not exist.

Source
has_key?(key : String) : Bool

Returns true if the environment variable named key exists or an secrets file of the same name is available.

Source
has_secret?(key : String) : Bool

Returns true if the secret named key exists.

Source