Standard Library
namespace env
The running process: its command-line arguments, its environment variables, and how it exits.
since 0.1.0-alpha.1linuxwindows
Overview
env::args() and env::name() describe how the program was started, env::get reads an
environment variable, and env::exit and env::setExitCode decide the exit status that the
program reports to the operating system. Programs that need to be tested without a real
environment can use the IEnv interface instead of calling these functions directly.
Description
env is a namespace of functions that answer questions about the process the program runs in.
env::args()is the argument list as anArray<string>. Element0is the program name and the real arguments start at index1, so the array is never empty. Each call returns a fresh array; useenv::args().skip(1)for just the arguments.env::name()is the program name, the same asenv::args().at(0).env::get(key)reads an environment variable and returnsstring?. It isNonewhen the variable is not set and""when it is set to an empty value, so the two cases are distinguishable.env::exit(code)andenv::setExitCode(code)control the exit status. They have their own entry,lang.exit-codes.
All of these are functions, not variables, and none of them can run during compile-time evaluation: a build never depends on the environment of the machine that compiled it.
Array<string> args = env::args();
console.writeln("program: ${env::name()}");
console.writeln("argument count: ${args.length() - 1}");
string? home = env::get("HOME");
if (home != None) {
console.writeln("home is set");
}
Run with leviathan --run program.lev -- first second, args.length() - 1 is 2, args.at(1) is
first, and args.at(2) is second.
Rules
env::args()[0]is the program name;env::args().skip(1)is the argument list.env::getreturnsNonefor an unset variable and""for a variable set to nothing.- None of the
envfunctions may be used incomptimecode.
Examples
Code that reads the environment is easier to test when it asks for the environment through the
IEnv interface instead of calling env directly. A fake can then stand in for the real thing.
This program injects a fake environment:
Reading the environment through IEnv
class FakeEnv : IEnv {
Array<string> canned;
new FakeEnv(Array<string> a) { canned = a; }
Array<string> args() => canned;
string? variable(string name) => name == "MODE" ? "test" : None;
}
void report(IEnv e) {
console.writeln("program: ${e.args().at(0)}");
string? mode = e.variable("MODE");
console.writeln("MODE set: ${mode != None}");
string? other = e.variable("OTHER");
console.writeln("OTHER set: ${other != None}");
}
void run() {
bind IEnv => FakeEnv(["demo", "-v"]);
report();
}
run();
program: demo
MODE set: true
OTHER set: false
See lang.capability-interfaces for the five interfaces of this kind and for the real
implementations that delegate to env.
Notes
env::variable does not exist: the function is env::get. IEnv.variable is the name used by
the interface, and the real implementation of it calls env::get.
Examples
console.writeln("starting");
env::setExitCode(0);
console.writeln("the program keeps running");
env::exit(0);
console.writeln("this line is never reached");
starting
the program keeps running
Functions
args
args() -> Array<string>The command-line arguments of the program.
Each call returns a fresh array. The first element is the name the program was started with, so the array is never empty; the arguments you passed start at index 1.
Returns
The program name followed by its arguments.
Examples
uses env;
Array<string> all = args();
console.writeln(all.length() >= 1);
Array<string> passed = args().skip(1);
console.writeln("arguments passed: ${passed.length()}");
true
arguments passed: 0
Reading the arguments of a real run
Array<string> passed = env::args().skip(1);
for (string a in passed) {
console.writeln("argument: ${a}");
}
See also: name
exit
exit(int code) -> voidEnd the program at once with an exit status.
Code after the call does not run. An exit status of 0 means success and any other value
reports a failure to whatever started the program. To record a status without stopping, use
setExitCode.
Parameters
- code
- The exit status to report.
Examples
console.writeln("before");
env::exit(0);
console.writeln("never printed");
before
Reporting a failure
if (env::args().length() > 5) {
console.writeln("too many arguments");
env::exit(2);
}
See also: setExitCode
get
get(string key) -> string | NoneRead an environment variable.
None means the variable is not set at all, which is different from a variable that is set
to the empty string, so a program can tell the two apart.
Parameters
- key
- The name of the variable.
Returns
The value of the variable, or None when it is not set.
Examples
The same lookup through the `IEnv` interface, which gives a repeatable result
IEnv environment = SystemEnv();
console.writeln(environment.variable("LEVIATHAN_DOCS_UNSET_VARIABLE") == None);
true
Reading a variable directly
string? home = env::get("HOME");
if (home != None) {
console.writeln("home is ${home}");
}
See also: IEnv
name
name() -> stringThe name the program was started with, which is the first element of args().
Returns
The program name.
Examples
uses env;
console.writeln(name() == args().at(0));
console.writeln(name().isEmpty());
true
false
See also: args
setExitCode
setExitCode(int code) -> voidRecord the exit status without stopping the program.
The program carries on and finishes normally; the recorded status is what it reports when it ends. A later call replaces the earlier code.
Parameters
- code
- The exit status to report when the program ends.
Examples
env::setExitCode(0);
console.writeln("still running");
console.writeln("finishing normally");
still running
finishing normally
Failing at the end
env::setExitCode(1);
console.writeln("finished with errors");
See also: exit