6.1 Command Line Parsing
The rhombus/cmdline library provides a cmdline.parse form to contain cmdline.flag and cmdline.args forms that together describe parsing for command-line arguments. A parse result is represented as a map that (by default) uses the flag names as symbol keys and #'args as a key to hold arguments that appear after all flags.
Here’s an example for a program that supports --channel, --volume, ++louder, and --quieter flags:
def config:
flag "--channel" name
flag "--volume" (n :: String.to_int):
~init: { #'volume: -20 }
~alias: "-v"
flag "++louder":
flag "--quieter":
at volume @(config[#'volume]).})
In the example, the --channel flag gets a default implementation that adds an argument string to the result map. The --volume flag also gets default handling, but adds an initial value for #'volume in the map to give it a default value, and supports the shorthand -v in place of --volume; also, its argument is annotated with String.to_int to allow only integer arguments to be passed on the command line (i.e., strings that can be converted to integers). Each of --channel and --volume is allowed at most once, but ++louder and --quieter are each allowed any number of times, and they have custom handling to adjust #'volume instead of adding #'louder and #'quieter keys to the map. In this example, cmdline.args is not used alongside cmdline.flag and cmdline.multi, which means that the program does not accept additional arguments after flags.
Since the example above uses cmdline.parse, then running the program will always parse command-line arguments. The cmdline.parser (with an “r” at the end) form has the same syntax, but produces a Parser object whose Parser.parse method can be called to trigger parsing and get a result map.
def config_getter:
flag "--channel" name
flag "--volume" (n :: String.to_int):
~init: { #'volume: -20 }
~alias: "-v"
flag "++louder":
flag "--quieter":
> config_getter.parse(~line: ["--volume", "-17",
"++louder",
"++louder",
"--channel", "The 90s"])
{#'channel: "The 90s", #'volume: -15}
> config_getter.parse(~line: ["--volume", "oops"],
~program: "demo")
demo: invalid argument
after flag: –volume
for: <n>
given: oops
> config_getter.print_help(~program: "demo")
usage: demo [<option> ...]
Each <option> starts with one of the flags listed below.
--channel <name>
--volume <n>, -v <n>
* ++louder
* --quieter
--help, -h
Show this information and exit, ignoring remaining arguments.
--
No argument after this flag is a flag.
* Asterisks indicate options allowed multiple times.
Multiple single-letter flags can be combined after one `-`.
For example, `-h-` is the same as `-h --`.