Reference

std/os/environment

std/os/src/environment.trb

The environment this process was started with: Environment reads one variable, lists every one as a value, and splits the search path; EnvironmentVariables is that list as a value a program can change and hand on.

Reach for Environment.get instead of a literal or a configuration file wherever a value is meant to come from outside the program - a host name, a feature flag, a secret. Inside a sandboxed script it needs the module std/os/environment granted, and only the variables matching the patterns granted there (environment "APP_*") are visible to it.

type Environment

native type Environment

The environment this process was started with: read, listed, and handed on as a value.

There is no Environment.set. Changing a variable of the running process is global mutable state, which the language does not have, and on POSIX it is a data race besides: setenv may move environ while another thread's getenv reads it. What setting a variable is for is almost always a child process, and a child is handed an EnvironmentVariables value.

Examples

const home = Environment.get "HOME"
print(home ?? "not set")

Related

fn get

native static fn get(name: String): String?

The value of name, or None if it is not set, or if the caller is not allowed to see it. On Windows a name is looked up without regard to case, as the system does: Path and PATH are one variable.

Examples

const home = Environment.get "HOME"
print(home ?? "not set")

Pitfalls

A missing variable and a variable the sandbox has not granted look identical: both answer None. A script cannot tell a capability it was denied from one that simply has nothing behind it.

fn variables

static fn variables(): EnvironmentVariables

Every variable the caller may see, as a value that can be changed and given to a child. Inside a sandbox it holds the variables the granted patterns match and nothing else.

Examples

const variables = Environment.variables()
print variables.get("PATH").isSome()

fn searchPath

static fn searchPath(): List<Path>

PATH split at the system's separator, each entry a Path, the empty ones dropped. On Windows the quotes an entry may be written in are removed, as the command interpreter does.

Examples

for directory in Environment.searchPath() {
  print directory
}

type EnvironmentVariables

type EnvironmentVariables with Show, Equals

A set of environment variables as a value. Names compare the way the target compares them: without regard to case on Windows, exactly everywhere else - so set("PATH", …) on Windows replaces an inherited Path, and keeps the spelling it was given.

Its show() lists the names only: an environment carries secrets, and a print of it must not.

Examples

var variables = EnvironmentVariables.empty()
variables.set "APP_MODE", "debug"
variables.set "NO_COLOR", "1"
variables.remove "NO_COLOR"
print variables

Related

fn empty

static fn empty(): EnvironmentVariables

No variables at all: the environment of a child that is to inherit nothing.

fn get

fn get(name: String): String?

The value of name, or None where it has none.

fn names

fn names(): List<String>

Every name, spelt as it was set, in the order the variables were first set.

fn set

var fn set(name: String, value: String)

Sets name to value, replacing a variable of the same name - on Windows, of any case.

fn remove

var fn remove(name: String)

Removes name, and on Windows every spelling of it. Removing a variable that is not there does nothing.

fn show

fn show(): String

The names only, never the values: EnvironmentVariables(APP_MODE, HOME).