OptionParser - Crystal 1.16.3

# class OptionParser

- OptionParser
- Reference
- Object

##
Overview

`OptionParser` is a class for command-line options processing. It supports:

- Short and long modifier style options (example: `-h`, `--help`)
- Passing arguments to the flags (example: `-f filename.txt`)
- Subcommands
- Automatic help message generation

Run `crystal` for an example of a CLI built with `OptionParser`.

NOTE To use `OptionParser`, you must explicitly import it with `require "option_parser"`

Short example:

    require "option_parser"

    upcase = false
    destination = "World"

    OptionParser.parse do |parser|
      parser.banner = "Usage: salute [arguments]"
      parser.on("-u", "--upcase", "Upcases the salute") { upcase = true }
      parser.on("-t NAME", "--to=NAME", "Specifies the name to salute") { |name| destination = name }
      parser.on("-h", "--help", "Show this help") do
        puts parser
        exit
      end
      parser.invalid_option do |flag|
        STDERR.puts "ERROR: #{flag} is not a valid option."
        STDERR.puts parser
        exit(1)
      end
    end

    destination = destination.upcase if upcase
    puts "Hello #{destination}!"

#
Subcommands

`OptionParser` also supports subcommands.

Short example:

    require "option_parser"

    verbose = false
    salute = false
    welcome = false
    name = "World"
    parser = OptionParser.new do |parser|
      parser.banner = "Usage: example [subcommand] [arguments]"
      parser.on("salute", "Salute a name") do
        salute = true
        parser.banner = "Usage: example salute [arguments]"
        parser.on("-t NAME", "--to=NAME", "Specify the name to salute") { |_name| name = _name }
      end
      parser.on("welcome", "Print a greeting message") do
        welcome = true
        parser.banner = "Usage: example welcome"
      end
      parser.on("-v", "--verbose", "Enabled verbose output") { verbose = true }
      parser.on("-h", "--help", "Show this help") do
        puts parser
        exit
      end
    end

    parser.parse

    if salute
      STDERR.puts "Saluting #{name}" if verbose
      puts "Hello #{name}"
    elsif welcome
      STDERR.puts "Welcoming #{name}" if verbose
      puts "Welcome!"
    else
      puts parser
      exit(1)
    end

##
Defined in:

option_parser.cr

##
Constructors

- .new(*, gnu_optional_args : Bool = false)

  Creates a new parser.

- .new(*, gnu_optional_args : Bool = false, &)

  Creates a new parser, with its configuration specified in the block.

- .parse(args = ARGV, *, gnu_optional_args : Bool = false, &) : self

  Creates a new parser, with its configuration specified in the block, and uses it to parse the passed args (defaults to `ARGV`).

##
Instance Method Summary

- #banner=(banner : String | Nil)

  Establishes the initial message for the help printout.

- #before_each(&before_each : String -> )

  Sets a handler which runs before each argument is parsed.

- #gnu_optional_args=(gnu_optional_args : Bool)

  Returns whether the GNU convention is followed for optional arguments.

- #gnu_optional_args? : Bool

  Returns whether the GNU convention is followed for optional arguments.

- #invalid_option(&invalid_option : String -> )

  Sets a handler for option arguments that didn't match any of the setup options.

- #missing_option(&missing_option : String -> )

  Sets a handler for when a option that expects an argument wasn't given any.

- #on(short_flag : String, long_flag : String, description : String, &block : String -> )

  Establishes a handler for a pair of short and long flags.

- #on(flag : String, description : String, &block : String -> )

  Establishes a handler for a flag or subcommand.

- #parse(args = ARGV) : Nil

  Parses the passed args (defaults to `ARGV`), running the handlers associated to each option.

- #separator(message = "") : Nil

  Adds a separator, with an optional header message, that will be used to print the help.

- #stop : Nil

  Stops the current parse and returns immediately, leaving the remaining flags unparsed.

- #to_s(io : IO) : Nil

  Returns all the setup options, formatted in a help message.

- #unknown_args(&unknown_args : Array(String), Array(String) -> )

  Sets a handler for regular arguments that didn't match any of the setup options.

### Instance methods inherited from class `Reference`

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil) same?, to_s(io : IO) : Nil to_s

### Constructor methods inherited from class `Reference`

new new, unsafe_construct(address : Pointer, *args, **opts) : self unsafe_construct

### Class methods inherited from class `Reference`

pre_initialize(address : Pointer) pre_initialize

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io, root : String)
from_json(string_or_io) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Constructor Detail

def self.new(*, gnu_optional_args : Bool = false) #

Creates a new parser.

Refer to `#gnu_optional_args?` for the behaviour of the named parameter.

def self.new(*, gnu_optional_args : Bool = false, &) #

Creates a new parser, with its configuration specified in the block.

Refer to `#gnu_optional_args?` for the behaviour of the named parameter.

def self.parse(args = ARGV, *, gnu_optional_args : Bool = false, &) : self #

Creates a new parser, with its configuration specified in the block, and uses it to parse the passed args (defaults to `ARGV`).

Refer to `#gnu_optional_args?` for the behaviour of the named parameter.

##
Instance Method Detail

def banner=(banner : String | Nil) #

Establishes the initial message for the help printout. Typically, you want to write here the name of your program, and a one-line template of its invocation.

Example:

    require "option_parser"

    parser = OptionParser.new
    parser.banner = "Usage: crystal [command] [switches] [program file] [--] [arguments]"

def before_each(&before_each : String -> ) #

Sets a handler which runs before each argument is parsed. This callback is not passed flag arguments. For example, `--foo=foo_arg --bar bar_arg` would pass `--foo=foo_arg` and `--bar` to the callback only.

You typically use this to implement advanced option parsing behaviour such as treating all options after a filename differently (along with `#stop`).

def gnu_optional_args=(gnu_optional_args : Bool) #

Returns whether the GNU convention is followed for optional arguments.

If true, any optional argument must follow the preceding flag in the same token immediately, without any space inbetween:

    require "option_parser"

    OptionParser.parse(%w(-a1 -a 2 -a --b=3 --b 4), gnu_optional_args: true) do |parser|
      parser.on("-a", "--b [x]", "optional") { |x| p x }
      parser.unknown_args { |args, _| puts "Remaining: #{args}" }
    end

Prints:

    "1"
    ""
    ""
    "3"
    ""
    Remaining: ["2", "4"]

Without `gnu_optional_args: true`, prints the following instead:

    "1"
    "2"
    "--b=3"
    "4"
    Remaining: []

def gnu_optional_args? : Bool #

Returns whether the GNU convention is followed for optional arguments.

If true, any optional argument must follow the preceding flag in the same token immediately, without any space inbetween:

    require "option_parser"

    OptionParser.parse(%w(-a1 -a 2 -a --b=3 --b 4), gnu_optional_args: true) do |parser|
      parser.on("-a", "--b [x]", "optional") { |x| p x }
      parser.unknown_args { |args, _| puts "Remaining: #{args}" }
    end

Prints:

    "1"
    ""
    ""
    "3"
    ""
    Remaining: ["2", "4"]

Without `gnu_optional_args: true`, prints the following instead:

    "1"
    "2"
    "--b=3"
    "4"
    Remaining: []

def invalid_option(&invalid_option : String -> ) #

Sets a handler for option arguments that didn't match any of the setup options.

You typically use this to display a help message. The default behaviour is to raise `InvalidOption`.

def missing_option(&missing_option : String -> ) #

Sets a handler for when a option that expects an argument wasn't given any.

You typically use this to display a help message. The default behaviour is to raise `MissingOption`.

def on(short_flag : String, long_flag : String, description : String, &block : String -> ) #

Establishes a handler for a pair of short and long flags.

See the other definition of `#on` for examples. This method does not support subcommands.

def on(flag : String, description : String, &block : String -> ) #

Establishes a handler for a flag or subcommand.

Flags must start with a dash or double dash. They can also have an optional argument, which will get passed to the block. Each flag has a description, which will be used for the help message.

Subcommands are any flag passed which does not start with a dash. They cannot take arguments. When a subcommand is parsed, all subcommands are removed from the OptionParser, simulating a "tree" of subcommands. All flags remain valid. For a longer example, see the examples at the top of the page.

Examples of valid flags:

- `-a`, `-B`
- `--something-longer`
- `-f FILE`, `--file FILE`, `--file=FILE` (these will yield the passed value to the block as a string)

Examples of valid subcommands:

- `foo`, `run`

def parse(args = ARGV) : Nil #

Parses the passed args (defaults to `ARGV`), running the handlers associated to each option.

def separator(message = "") : Nil #

Adds a separator, with an optional header message, that will be used to print the help. The separator is placed between the flags registered (`#on`) before, and the flags registered after the call.

This way, you can group the different options in an easier to read way.

def stop : Nil #

Stops the current parse and returns immediately, leaving the remaining flags unparsed. This is treated identically to `--` being inserted behind the current parsed flag.

def to_s(io : IO) : Nil #

Returns all the setup options, formatted in a help message.

def unknown_args(&unknown_args : Array(String), Array(String) -> ) #

Sets a handler for regular arguments that didn't match any of the setup options.

You typically use this to get the main arguments (not modifiers) that your program expects (for example, filenames). The default behaviour is to do nothing. The arguments can also be extracted from the args array passed to `#parse` after parsing.