OptionParser for Ruby

# Summary

Library for command line option analysis.

features:

1. It is possible <option switch of a short form and a long form> to exist together. It is also possible in one to bring the switch of a short form together.
2. It is possible to write bringing specification and the handler of the switch together respectively in one place.
3. The argument of the switch is converted into the class which automatically specifies it.
4. The option summary can be made.
5. The option can be added on the way later.

## Class tree

- OptionParser front end
- OptionParser::Switch each switches
- OptionParser::List options list

- OptionParser::ParseError errors on parsing

  - OptionParser::AmbiguousOption
  - OptionParser::NeedlessArgument
  - OptionParser::MissingArgument
  - OptionParser::InvalidOption

  - OptionParser::InvalidArgument

    - OptionParser::AmbiguousArgument

## Object relations

    +--------------+
    | OptionParser |<>-----+
    +--------------+       |          	         +--------+
                           |          	       ,-| Switch |
         on_head -------->+---------------+    /  +--------+
         accept/reject -->| List        	 |<|>-
                          |             	 |<|>-  +----------+
         on ------------->+---------------+    `-| argument |
                          :             	 :      |  class   |
                          +---------------+      |==========|
         on_tail -------->|             	 |      |pattern   |
                          +---------------+      |----------|
    OptionParser.accept ->| DefaultList 	 |      |converter |
                 reject   |(shared between|      +----------+
                          | all instances)|
                          +---------------+

# Classes & Modules

## OptionParser::Switch

Individual switch class.

### Instance methods

`OptionParser::Switch#parse(arg, val) {semi-error handler}`

  Parses argument, convert and returns arg, block and result of conversion.

  Arguments to @conv

    substrings matched to @pattern, $&, $1, $2 and so on.

  Parameters:
    arg

      argument string follows the switch.

    val

      following argument.

    `block`

      `yields` at semi-error condition, instead of raises exception.

## OptionParser::List

Simple option list providing mapping from short and/or long option string to OptionParser::Switch, and mapping from acceptable argument to matching pattern and converter pair. Also provides summary feature.

### Class methods

### Instance methods

`OptionParser::List#atype`

  Map from acceptable argument types to pattern and converter pairs.

`OptionParser::List#short`

  Map from short style option switches to actual switch objects.

`OptionParser::List#long`

  Map from long style option switches to actual switch objects.

`OptionParser::List#list`

  List of all switches and summary string.

`OptionParser::List#prepend(switch, short_opts, long_opts, nolong_opts)`

  Inserts switch at head of the list, and associates short, long and negated long options.

`OptionParser::List#append(switch, short_opts, long_opts, nolong_opts)`

  Appends switch at tail of the list, and associates short, long and negated long options.

  Parameters:
    switch

      OptionParser::Switch instance to be inserted.

    short_opts

      list of short style options.

    long_opts

      list of long style options.

    nolong_opts

      list of long style options with `"no-"` prefix.

`OptionParser::List#search(id, key) [{block}]`

  Searches key in id list.

  Parameters:
    id

      searching list.

    k

      searching key.

    `Block`

      yielded with the found value when succeeded.

`OptionParser::List#complete(id, opt, *pat, &block)`

  Searches list id for opt and *pat.

  Parameters:
    id

      searching list.

    opt

      searching key.

    *pat

      optional pattern for completion.

    `Block`

      yielded with the found value when succeeded.

`OptionParser::List#summarize(*args) {...}`

  Making summary table, yields the `block` with each lines. Each elements of `@list` should be able to `summarize`.

  Parameters:
    args

      passed to elements#summarize through.

    `block`

      to be passed each lines(without newline).

## OptionParser

The front-end of `OptionParser`.

### Constants

`OptionParser::ArgumentStyle`

  Enumeration of acceptable argument styles; possible values are:

  OptionParser::NO_ARGUMENT

    the switch takes no arguments. (`:NONE`)

  OptionParser::REQUIRED_ARGUMENT

    the switch requires an argument. (`:REQUIRED`)

  OptionParser::OPTIONAL_ARGUMENT

    the switch requires an optional argument, that is, may take or not. (`:OPTIONAL`)

  Use like `--switch=argument`(long style) or `-Xargument`(short style). For short style, only portion matched to argument pattern is dealed as argument.

### Class methods

`OptionParser.with([banner[, width[, indent]]]) [{...}]`

  Initializes new instance, and evaluates the block in context of the instance if called as iterator. This behavior is equivalent to older `new`. This is deprecated method.

  cf. OptionParser.new

  Parameters:
    banner

      banner message.

    width

      summary width.

    indent

      summary indent.

    `Block`

      to be evaluated in the new instance context.

`OptionParser.inc(arg[, default])`
`OptionParser#inc(arg[, default])`

  Returns incremented value of default according to arg.

`OptionParser.new([banner[, width[, indent]]]) [{...}]`

  Initializes the instance, and yields itself if called as iterator.

  Parameters:
    banner

      banner message.

    width

      summary width.

    indent

      summary indent.

    `Block`

      to be evaluated in the new instance context.

`OptionParser.terminate([arg])`

  Terminates option parsing. Optional parameter arg would be pushed back if given.

  Parameters:
    arg

      string pushed back to be first non-option argument

`OptionParser.accept(t, [pat]) {...}`
`OptionParser#accept(t, [pat]) {...}`

  Directs to accept specified class argument.

  Parameters:
    t

      argument class specifier, any object including Class.

    pat

      pattern for argument, defaulted to t if it respond to `match`.

    `Block`

      receives argument string and should be convert to desired class.

`OptionParser.reject(t)`
`OptionParser#reject(t)`

  Directs to reject specified class argument.

  Parameters:
    t

      argument class specifier, any object including Class.

### Instance methods

`OptionParser#banner`
`OptionParser#banner=(heading)`

  Heading banner preceding summary.

`OptionParser#summary_width`
`OptionParser#summary_width=(width)`

  Width for option list portion of summary. Must be `Numeric`.

`OptionParser#summary_indent`
`OptionParser#summary_indent=(indent)`

  Indentation for summary. Must be `String` (or have `+ String`).

`OptionParser#program_name`
`OptionParser#program_name=(name)`

  Program name to be emitted in error message and default banner, defaulted to `$0`.

`OptionParser#version`
`OptionParser#version=(ver)`

  Version.

`OptionParser#release`
`OptionParser#release=(rel)`

  Release code.

`OptionParser#ver`

  Returns version string from program_name, `version` and `release`.

`OptionParser#top`

  Subject of on/on_head, accept/reject.

`OptionParser#base`

  Subject of on_tail.

`OptionParser#new`

  Pushes a new `List`.

`OptionParser#remove`

  Removes the last `List`.

`OptionParser#summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent)`

  Puts option summary into to, and returns to.

  Parameters:
    to

      output destination, which must have method <<. Defaulted to `[]`.

    width

      width of left side. Defaulted to @summary_width

    max

      maximum length allowed for left side. Defaulted to `width - 1`

    indent

      indentation. Defaulted to @summary_indent

    `Block`

      yields with each line if called as iterator.

`OptionParser#to_str`
`OptionParser#to_s`

  Returns option summary string.

`OptionParser#to_a`

  Returns option summary list.

`OptionParser#switch`

  Creates OptionParser::Switch.

  Parameters:
    *opts

      option definition:

      argument style

        see OptionParser::ArgumentStyle

      argument pattern

        acceptable option argument format, must pre-defined with OptionParser.accept or OptionParser#accept, or `Regexp`. This can appear once or assigned as `String` if not present, otherwise causes exception `ArgumentError`.

        cf. Acceptable argument classes.

      Hash
      Array

        possible argument values.

      Proc
      Method

        alternative way to give the handler.

      "--switch=MANDATORY", "--switch[=OPTIONAL]", "--switch"

        specifies long style switch that takes mandatory, optional and no argument, respectively.

      "-xMANDATORY", "-x[OPTIONAL]", "-x"

        specifies short style switch that takes mandatory, optional and no argument, respectively.

      "-[a-z]MANDATORY", "-[a-z][OPTIONAL]", "-[a-z]"

        special form short style switch that matches character range(not fullset of regular expression).

      "=MANDATORY", "=[OPTIONAL]"

        argument style and description.

      "description", ...

        description for this option.

    `Block`

      handler to convert option argument to arbitrary `Class`.

`OptionParser#on(*opts) [{...}]`
`OptionParser#def_option(*opts) [{...}]`
`OptionParser#on_head(*opts) [{...}]`
`OptionParser#def_head_option(*opts) [{...}]`
`OptionParser#on_tail(*opts) [{...}]`
`OptionParser#def_tail_option(*opts) [{...}]`

  Defines option switch and handler. `on_head`, `def_head_option` and `on_tail`, `def_tail_option` put the switch at head and tail of summary, respectively.

  cf. OptionParser#switch.

`OptionParser#order(*argv) [{...}]`
`OptionParser#order!([argv = ARGV]) [{...}]`

  Parses argv in order. When non-option argument encountered, yields it if called as iterator, otherwise terminates the parse process. Returns rest of argv left unparsed.

  `order!` takes argument array itself, and removes switches destructively. Defaults to parse ARGV.

  Parameters:
    argv

      command line arguments to be parsed.

    `Block`

      called with each non-option argument.

`OptionParser#permute(*argv)`
`OptionParser#permute!([argv = ARGV])`

  Parses argv in permutation mode, and returns list of non-option arguments.

  `permute!` takes argument array itself, and removes switches destructively. Defaults to parse ARGV.

  Parameters:
    argv

      command line arguments to be parsed.

`OptionParser#parse(*argv)`
`OptionParser#parse!([argv = ARGV])`

  Parses argv in order when environment variable `POSIXLY_CORRECT` is set, otherwise permutation mode

  `parse!` takes argument array itself, and removes switches destructively. Defaults to parse ARGV.

  Parameters:
    argv

      command line arguments to be parsed.

# Acceptable argument classes

Object

  any string, and no conversion. this is fall-back.

String

  any none-empty string, and no conversion.

Integer

  Ruby/C-like integer, octal for `0-7` sequence, binary for `0b`, hexadecimal for `0x`, and decimal for others; with optional sign prefix. Converts to `Integer`.

Float

  Float number format, and converts to `Float`.

Numeric

  Generic numeric format, and converts to `Integer` for integer format, `Float` for float format.

OptionParser::DecimalInteger

  Decimal integer format, to be converted to `Integer`.

OptionParser::OctalInteger

  Ruby/C like octal/hexadecimal/binary integer format, to be converted to `Integer`.

OptionParser::DecimalNumeric

  Decimal integer/float number format, to be converted to `Integer` for integer format, `Float` for float format.

TrueClass

  Boolean switch, which means whether it is present or not, whether it is absent or not with prefix `no-`, or it takes an argument `yes/no/true/false/+/-`.

FalseClass

  Similar to TrueClass, but defaulted to `false`.

Array

  List of strings separated by ","

# Exceptions

## OptionParser::ParseError

Base class of exceptions from OptionParser

### Superclass

`RuntimeError`

### Constants

OptionParser::ParseError::Reason

  Reason caused error.

### Instance methods

`OptionParser::ParseError#recover(argv)`

  Push backs erred argument(s) to argv.

`OptionParser::ParseError#reason`

  Returns error reason. Override this to I18N.

`OptionParser::ParseError#inspect`

  Returns inspection string.

`OptionParser::ParseError#message`
`OptionParser::ParseError#to_s`
`OptionParser::ParseError#to_str`

  Default stringizing method to emit standard error message.

## OptionParser::AmbiguousOption

Raises when encountered ambiguously completable string.

### Superclass

OptionParser::ParseError

## OptionParser::NeedlessArgument

Raises when encountered argument for switch defined as which takes no argument.

### Superclass

OptionParser::ParseError

## OptionParser::MissingArgument

Raises when no argument found for switch defined as which needs argument.

### Superclass

OptionParser::ParseError

## OptionParser::InvalidOption

Raises when undefined switch.

### Superclass

OptionParser::ParseError

## OptionParser::InvalidArgument

Raises when the given argument does not match required format.

### Superclass

OptionParser::ParseError

## OptionParser::AmbiguousArgument

Raises when the given argument word can't completed uniquely.

### Superclass

OptionParser::InvalidArgument

# Miscellaneous

## OptionParser::Arguable

Extends command line arguments array to parse itself.

`OptionParser::Arguable#options=(opt)`

  Sets OptionParser object, when opt is `false` or `nil`, methods OptionParser::Arguable#options and OptionParser::Arguable#options= are undefined. Thus, there is no ways to access the OptionParser object via the receiver object.

`OptionParser::Arguable#options`

  Actual OptionParser object, automatically created if not yet.

  If called as iterator, yields with the OptionParser object and returns the result of the block. In this case, rescues any OptionParser::ParseError exceptions in the block, just emits error message to STDERR and returns `nil`.

  Parameters:
    `block`

      Yielded with the OptionParser instance.

`OptionParser::Arguable#order!`
`OptionParser::Arguable#permute!`
`OptionParser::Arguable#parse!`

  Parses self destructively, and returns self just contains rest arguments left without parsed.

## OptionParser::Acceptables

Acceptable argument classes. Now contains `DecimalInteger`, `OctalInteger` and `DecimalNumeric`. see Acceptable argument classes.

# Example

    require 'optparse'

    $0 = File.basename($0)

    # keywords
    CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
    CODE_ALIASES = {"jis" => "iso-2022-jp", "sjis" => "shift_jis"}
    POSSIBLE_CODES = "(#{(CODES+CODE_ALIASES.keys).join(',')})"

    vars = {}
    ARGV.options do
      |opts|
      opts.banner = "Usage: #{$0} [options] argv...\n"

      # separater
      opts.on_tail
      opts.on_tail("common options:")

      # no argument, shows at tail
      opts.on_tail("--help", "show this message") {puts opts; exit}

      # mandatory argument
      opts.on("-r", "--require=LIBRARY", String,
    	  "require the LIBRARY, before",
    	  "executing your script") {|vars[:library]|}

      # optional argument
      opts.on("-i", "--inplace=[EXTENSION]",
    	  "edit ARGV files in place", # multiline description
    	  "(make backup if EXTENSION supplied)") {|vars[:inplace]| vars[:inplace] ||= ''}

      opts.on("-N=[NUM]", Integer) {|vars[:number]|}

      # additional class
      # opts.on("-t", "--time=TIME", Time, "it's the time") {|vars[:time]|}

      # limit argument syntax
      opts.on("-[0-7]", "-F", "--irs=[OCTAL]", OptionParser::OctalInteger,
    	  "specify record separator", "(\\0, if no argument)") {|vars[:irs]|}

      # boolean switch(default true)
      vars[:exec] = true
      opts.on("-n", "--no-exec", "not really execute") {|vars[:exec]|}

      # array
      opts.on("-a", "--list[=LIST,LIST]", Array, "list") {|vars[:list]|}

      # fixed size array
      opts.on("--pair[=car,cdr]", Array, "pair") {|vars[:x], vars[:y]|}

      # keyword completion
      opts.on("--code=CODE", CODES, CODE_ALIASES, "select coding system", POSSIBLE_CODES) {|vars[:code]|}

      # optional argument with keyword completion
      opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") {|vars[:type]|}

      # boolean switch with optional argument(default false)
      opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") {|vars[:verbose]|}

      # easy way, set local variable
      opts.on("-q", "--quit", "quit when ARGV is empty") {|vars[:quit]|}

      # adding on the fly
      opts.on("--add=SWITCH=[ARG]", "add option on the fly", /\A(\w+)(?:=.+)?\Z/) do
        |opt, var|
        opts.on("--#{opt}", "added in runtime", &eval("proc {|vars[:#{var}]|}"))
      end

      opts.on_head("specific optins:")

      # no argument
      opts.on_tail("--version", "show version") do
        puts OptionParser::Version.join('.')
        exit
      end
      opts.parse!
    end

    if (Fixnum === :-)
      class << vars
        def inspect
          "{" + collect {|k,v| ":#{k.id2name}=>#{v.inspect}"}.join(", ") + "}"
        end
      end
    end
    p vars
    (puts ARGV.options; exit) if vars[:quit]
    ARGV.options = nil		# no more parse
    puts "ARGV = #{ARGV.join(' ')}" if !ARGV.empty?
    #opts.variable.each {|sym| puts "#{sym} = #{opts.send(sym).inspect}"}