std/option_parser
import std/option_parser to use it. Source: src/std/option_parser.iyi at v0.18.0.
on("--name VALUE", "help") { |v| ... } and on("-h", "help") { } register flags, and on("--color [WHEN]", "help") one whose value may be left out. parse walks Program.args (or the array given), calls the blocks, and answers the leftover operands.
op = OptionParser.new
op.banner = "usage: tool [options] COMMAND"
op.on("-v", "--verbose", "say more") { verbose = true }
op.on("-n NAME", "--name=NAME", "who") { |v| name = v }
op.separator("commands:")
op.on("deploy", "ship it") do
op.on("-f", "--force", "even if dirty") { force = true }
end
puts op # the banner, then a line for each flag and commandA pair, -v and --verbose, is one flag spelled two ways; a value either spelling states, -n NAME or --name=NAME, both take.
A command is a name with no dash, and is one only as the first operand: tool deploy -f runs deploy's block, which registers what follows it
- its flags, and the commands below it, which replace the ones beside
it. Flags registered before the command still apply after it, where the other library forgets them; a name after an operand is an operand.
What the person typed wrong is the program's to answer, the way Crystal's OptionParser has it: invalid_option { |flag| ... } is handed an unknown flag and a value given to a flag that takes none, missing_option { |flag| ... } a flag that takes a value and is last, and parsing goes on after either. With no handler set they panic - unknown flag: --x, flag --x takes no value, flag --name needs a value - which is a bug report where a usage line was wanted, so a program reading its own command line sets both.
OptionParserclass
pub class OptionParser
# What a flag does with the argument after it: `--name VALUE` needs one,
# `--color [WHEN]` takes one unless it is missing or is a flag itself,
# and `--verbose` takes none.
enum Value : Int32
None = 0
Required = 1
Optional = 2
end
def banner : String | ::Nil
# The help's first line, "options:" until it is set.
def banner=(text : String) : Nil
def help : String
def initialize
def invalid_option(&block : (String -> Nil)) : Nil
def missing_option(&block : (String -> Nil)) : Nil
# One flag spelled two ways, `-v` and `--verbose`: the value either
# states, both take.
def on(short : String, long : String, description : String, &block : (String -> Nil)) : Nil
# A value is taken by `--name VALUE`, `--name=VALUE`, `-n VALUE` and
# `-nVALUE`, the four spellings the other library reads. Only the space
# form was: `--name=VALUE` was stored under the key `--name=VALUE`, which
# no argument ever looks up, and `-nVALUE` refused itself as not a flag.
# A short flag is one character, not one byte: `-é` was refused too.
#
# A bracketed value, `--color [WHEN]`, `-c [WHEN]` or `-c[WHEN]`, may be
# left out, as the other library reads the brackets. It was a required
# value: `--color` last panicked "flag --color needs a value", and
# `--color -v` handed `-v` to `--color` instead of running it.
def on(flag : String, description : String, &block : (String -> Nil)) : Nil
def parse(args : Array(String)) : Array(String)
def parse : Array(String)
# A line of its own in the help, between the flags and commands
# registered before it and after it.
def separator(text : String) : Nil
def to_s : String
end
Flag parsing, written in iyi.