要約

コマンドラインオプション解析用ライブラリ。

サポートしている機能:

  1. 短い形式と長い形式のオプションスイッチを混在可能。 短形式のスイッチは一つにまとめることも可能。
  2. スイッチの指定とハンドラをそれぞれ一箇所にまとめて書ける。
  3. スイッチの引数は自動的に指定したクラスに変換される。
  4. オプションサマリを作れる。
  5. 後から、あるいは途中でオプションを追加できる。

概要

クラス構成

オブジェクト関連図

+--------------+
| OptionParser |<>-----+
+--------------+       |          	       +--------+
                       |          	     ,-| Switch |
     on_head -------->+-------------+    /  +--------+
     accept/reject -->| List        |<|>-
                      |             |<|>-  +----------+
     on ------------->+-------------+    `-| argument |
                      :             :      |  class   |
                      +-------------+      |==========|
     on_tail -------->|             |      |pattern   |
                      +-------------+      |----------|
OptionParser.accept ->| DefaultList |      |converter |
             reject   |(全インスタン|      +----------+
                      | スで共有)   |
                      +-------------+

クラス & モジュール

OptionParser::Switch

各スイッチのクラス。

インスタンスメソッド

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

引数をパース、変換してargblock、変換結果を返す。

@convへの引数:

@patternにマッチした部分文字列のリスト、 $&, $1, $2 など。

Parameters:
arg

スイッチに直に指定されていた引数の文字列。

val

スイッチ以降の引数。

block

エラーかも知れないときに例外をyieldする。

OptionParser::Switch#summarize(sdone, ldone, width, max, indent)

オプションサマリを作る。

Parameters:
sdone

すでにサマリに入っている短形式オプションをキーとするハッシュ。

ldone

すでにサマリに入っている長形式オプションをキーとするハッシュ。

width

左側のオプションリスト部分の幅。 オプションの説明はその右側、width桁目から始まる。

max

左側の最大幅。 オプションはmax桁以内に詰められる。

indent

各行をインデントするための文字列。

block

各行ごとに渡される(改行は付かない)。

OptionParser::Switch#-@

反転したブーリアンスイッチ(@blockに渡される引数が反転される)を作る

OptionParser::List

単一のオプションリスト、短/長形式のオプション文字列からスイッチへのマッピング、受け付けられる引数タイプからパターンとコンバータへのマッピングを提供する。 サマリもここで提供される。

クラスメソッド

インスタンスメソッド

OptionParser::List#atype

引数タイプからパターン/コンバータのペアへのマップ。

OptionParser::List#short

短形式のオプションスイッチからスイッチオブジェクトへのマップ。

OptionParser::List#long

長形式のオプションスイッチからスイッチオブジェクトへのマップ。

OptionParser::List#list

全スイッチとサマリ文字列のリスト。

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

switchをリストの頭に挿入して、短/長/否定形式のオプションに対応させる。

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

switchをリストの最後に追加して、短/長/否定形式のオプションに対応させる。

Parameters:
switch

挿入するOptionParser::Switchインスタンス。

short_opts

switchに対応する短形式オプションのリスト。

long_opts

switchに対応する長形式オプションのリスト。

nolong_opts

"no-"のつく否定形式のオプションのリスト。

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

keyidのリストから検索する。

Parameters:
id

検索するリスト。

k

検索するキー。

Block

見付かったときにその値で呼び出される。

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

optidのリストから*patで補完して検索する。

Parameters:
id

検索するリスト。

opt

検索するキー。

*pat

補完に使うパターン。

Block

見付かったときにその値で呼び出される。

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

サマリテーブルを作る。 一行ごとにblockを呼び出す。 @listの要素はsummarizeできる必要がある。

Parameters:
args

そのまま各要素の summarize に渡される。

block

各行ごとに渡される(改行は付かない)。

OptionParser

オプションパーサのフロントエンド。

定数

OptionParser::ArgumentStyle

取りうる引数のスタイルの種類。 値はそれぞれ:

OptionParser::NO_ARGUMENT

引数を取らないスイッチ。

OptionParser::REQUIRED_ARGUMENT

引数が必須のスイッチ。 直後に引数が=で指定されていなければ、次の文字列を引数とみなす。 空の引数を指定するときは、=だけをつける。

OptionParser::OPTIONAL_ARGUMENT

オプショナルな引数を取るスイッチ。 つまり引数を付けても付けなくてもよい。

引数を指定するときは--switch=argument(長形式)か、 -Xargument(短形式)とする。 短形式では、引数パターンにマッチする部分だけが引数として認識される。

OptionParser::DefaultList

'--'のように全OptionParserインスタンスで共有するスイッチや、デフォルトの引数クラスを持つ。

クラスメソッド

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

新しいインスタンスを作成して、イテレータとして呼ばれているときにはブロックをそのインスタンスのコンテクストで評価してから、返す。 この動作は以前のnewと同じだが、depricatedなメソッド。

cf. OptionParser#initialize

Parameters:
banner

バナーメッセージ。

width

サマリの幅。

indent

サマリのインデント文字列。

Block

作成したインスタンスのコンテクストで評価される。

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

インスタンスを初期化する。 イテレータとして呼ばれている場合は、自分自身を渡す。

Parameters:
banner

バナーメッセージ。 デフォルトはnil

width

サマリの幅。 デフォルトは32

indent

サマリのインデント。 デフォルトは空白4個。

Block

selfが渡される。

OptionParser.terminate([arg])

オプションの解析を終了させる。 省略可能なargが与えられていると、コマンドライン引数に戻される。

Parameters:
arg

最初のオプションでない引数として戻される文字列。

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

指定したクラスのオプション引数を受け付けられるようにする。

Parameters:
t

引数クラスを指定するオブジェクト、通常はClass

pat

引数のパターン。 tmatchを持っていればそれがデフォルト。

Block

引数の文字列を受け取って要求されるクラスに変換する。

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

指定したクラスのオプション引数を受け付けないようにする。

Parameters:
t

引数クラスを指定するオブジェクト。

インスタンスメソッド

OptionParser#banner
OptionParser#banner=(heading)

サマリの先頭に出力されるバナー。

OptionParser#summary_width
OptionParser#summary_width=(width)

サマリのオプションリスト部分の幅。 Numericである要がある。

OptionParser#summary_indent
OptionParser#summary_indent=(indent)

サマリのインデント。 Stringでなければならない(もしくは String+できるモノ)。

OptionParser#program_name
OptionParser#program_name=(name)

エラーメッセージやデフォルトのバナーで出力されるプログラム名。 デフォルトは$0

OptionParser#top

on/on_headaccept/rejectの対象。

OptionParser#base

on_tailの対象。

OptionParser#new

新しいListを追加する。

OptionParser#remove

最後のListを削除する。

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

オプションサマリをtoに作る。 toを返す。

Parameters:
to

出力先。 <<メソッドが必要。 デフォルトは[]

width

左側、オプションリスト部の幅。 デフォルトは@summary_width

max

左側で使える最大幅。 デフォルトはwidth - 1

indent

インデント。 デフォルトは@summary_indent

Block

イテレータとして呼ばれていると、各行ごとに呼び出される。

OptionParser#to_str
OptionParser#to_s

オプションサマリ文字列を返す。

OptionParser#to_a

オプションサマリを配列として返す。

OptionParser#switch

OptionParser::Switchを作る。

Parameters:
opts

オプション定義。

引数スタイル

OptionParser::ArgumentStyle参照。

引数パターン

受け付けられるオプション引数の形式。 OptionParser.acceptOptionParser#acceptであらかじめ定義されているか、 Regexpなどのmatchメソッドを持つオブジェクトでなければならない。 これは一度だけ指定できる(もしなければObjectとみなされる)が、さもなければArgumentErrorを起こす。

cf. 引数として受け付けられるクラス.

Hash
Array

取り得る引数の値。

Proc
Method

handlerを与える別の手段。

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

それぞれ引数が必須、省略可能、無しの長形式スイッチ。

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

それぞれ引数が必須、省略可能、無しの短形式スイッチ。

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

キャラクタクラスにマッチする短形式のスイッチ (正規表現全てが使えるわけではない)。

"=MANDATORY", "=[OPTIONAL]"

引数スタイル。

"description", ...

このスイッチの説明。

Block

このスイッチが指定されたときに呼び出されるhandler

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) [{...}]

オプションスイッチとハンドラを定義する。 on_headdef_head_optionon_taildef_tail_optionはそれぞれスイッチをサマリの最初と最後におく。

cf. OptionParser#switch.

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

argvを出て来る順番にしたがって解析する。 オプションでない引数があると、イテレータとして呼ばれていればそれを渡して呼び出す。 さもなければ解析を終了する。 解析されずに残ったargvを返す。

order!は配列自身を受け取って、スイッチを破壊的に取り除く。 デフォルトではARGVを解析する。

Parameters:
argv

解析するコマンドライン引数の配列。

Block

オプションでない引数があると呼び出される。

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

argvを並び変えモードで解析して、オプションでない引数のリストを返す。

permute!は配列自身を受け取って、スイッチを破壊的に取り除く。 デフォルトではARGVを解析する。

Parameters:
argv

解析するコマンドライン引数の配列。

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

環境変数POSIXLY_CORRECTがセットされているときは順序通りに、それ以外は並べ変えモードで、argvを解析する。

parse!は配列自身を受け取って、スイッチを破壊的に取り除く。 デフォルトではARGVを解析する。

Parameters:
argv

解析するコマンドライン引数の配列。

引数として受け付けられるクラス

Object

任意の文字列、変換されない。 何も指定しないとこれになる。

String

任意の空でない文字列、変換されない。

Integer

Ruby/C的な整数、0で始まれば8進数、0bで始まれば2進数、 0xで始まれば16進数、それ以外は10進数とみなす。 符号も付けられる。 Integerに変換される。

Float

実数形式、Floatに変換される。

Numeric

汎用の数値、整数形式ならInteger、実数形式なら Floatに変換される。

OptionParser::DecimalInteger

10進整数、Integerに変換される。

OptionParser::OctalInteger

Ruby/C的な 8/16/2進整数、Integerに変換される。

OptionParser::DecimalNumeric

10進整数/実数形式。 整数形式ならInteger、実数形式なら Floatに変換される。

TrueClass

ブーリアンスイッチ、存在すれば真、またはno-が前に付いていれば偽。 もしくはyes/no/true/falseで示される値。

FalseClass

TrueClassと似ているが、デフォルトの値はfalse

Array

","区切り文字列。

例外

OptionParser::ParseError

OptionParserで発生する例外のベースクラス。

スーパークラス

RuntimeError

定数

OptionParser::ParseError::Reason

エラー原因。

インスタンスメソッド

OptionParser::ParseError#reason

エラーの理由を返す。

OptionParser::ParseError#inspect

可読形式の文字列を返す。

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

デフォルトの文字列化メソッド、標準的なエラーメッセージ用。

OptionParser::AmbiguousOption

補完が一意に決められないときに発生する。

スーパークラス

OptionParser::ParseError

OptionParser::NeedlessArgument

引数を取らないスイッチに引数が指定されていたときに発生する。

スーパークラス

OptionParser::ParseError

OptionParser::MissingArgument

引数が必要なスイッチに引数が無かったときに発生する。

スーパークラス

OptionParser::ParseError

OptionParser::InvalidOption

定義されていないスイッチで発生する。

スーパークラス

OptionParser::ParseError

OptionParser::InvalidArgument

与えられた引数がフォーマットに合わなかったときに発生する。

スーパークラス

OptionParser::ParseError

OptionParser::AmbiguousArgument

与えられた引数が一意に決定できなかったときに発生する。

スーパークラス

OptionParser::InvalidArgument

その他

OptionParser::Arguable

コマンドライン引数の配列に、自分自身をパースする機能を拡張する。 optparse.rbrequireすると、ARGVが拡張されている。

OptionParser::Arguable#options=

OptionParserオブジェクトをセットする。 optfalsenilなら、 OptionParser::Arguable#optionsメソッドと OptionParser::Arguable#options=メソッドが未定義にされる。 つまり、このレシーバ経由でOptionParserオブジェクトにアクセスする方法は無くなる。

OptionParser::Arguable#options [{...}]

実際のOptionParserオブジェクト。 設定されていなければ自動的に作られる。

イテレータとして呼ばれると、OptionParserオブジェクトと共に呼び出して、その結果を戻り値とする。 このとき、OptionParser::ParseError例外は補足され、エラーメッセージをSTDERRに表示するだけでnilを返す。

Parameters:
block

設定されているOptionParserのインスタンスとともに呼ばれる。

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

selfを破壊的にパースして、selfを返す。 パースされなかった文字列だけを残す。

OptionParser::Acceptables

OptionParserで定義されている、引数として受け付けられるパターンの定数を含んでいる。 今のところDecimalIntegerOctalIntegerDecimalNumeric引数として受け付けられるクラス参照。

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}"}