オプション -a, -b を受け付けるコマンドを作成する。
require 'optparse'
opt = OptionParser.new
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb -a foo bar -b baz
# => true
true
["foo", "bar", "baz"]
オプションの指定はコマンドの直後である必要はない(上の例で、-b はオプションと して認識されている)。ただし、環境変数 POSIXLY_CORRECT が定義してあると この挙動は変更される。
env POSIXLY_CORRECT=1 ruby ./sample.rb -a foo bar -b baz
# => true # -a はオプションと解釈
["foo", "bar", "-b", "baz"] # -b は非オプションと解釈
parse!() により、コマンドライン(ARGV)の解析を行う。 parse!() では、ARGV からオプションが取り除かれる。 これを避けるには parse() を使う。
require 'optparse'
opt = OptionParser.new
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }
# parse() の場合、ARGVは変更されない。
# オプションを取り除いた結果は argv に設定される。
argv = opt.parse(ARGV)
p argv
定義していないオプションを指定すると例外 OptionParser::InvalidOption が 発生する。(このようなときに usage を出力するには?)
ruby ./sample.rb -c
/usr/local/lib/ruby/1.9/optparse.rb:1428:in `complete': invalid option: -c (OptionParser::InvalidOption)
from /usr/local/lib/ruby/1.9/optparse.rb:1426:in `catch'
from /usr/local/lib/ruby/1.9/optparse.rb:1426:in `complete'
from /usr/local/lib/ruby/1.9/optparse.rb:1287:in `order!'
from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `catch'
from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `order!'
from /usr/local/lib/ruby/1.9/optparse.rb:1336:in `permute!'
from /usr/local/lib/ruby/1.9/optparse.rb:1363:in `parse!'
from /usr/local/lib/ruby/1.9/optparse.rb:1356:in `parse'
from ./sample.rb:9
OptionParser 自体は、どのオプションが指定されたかを記憶しない。 後の処理の方で、オプションによる条件判断を加えるには、 他のコンテナに格納する(しかない?)。
require 'optparse'
opt = OptionParser.new
OPTS = {}
opt.on('-a') {|v| OPTS[:a] = v }
opt.on('-b') {|v| OPTS[:b] = v }
opt.parse!(ARGV)
p ARGV
p OPTS
ruby sample.rb -a foo bar -b baz
# => ["foo", "bar", "baz"]
{:a=>true, :b=>true}
OprionParser.new はブロックを受け付ける。ブロックの引数は生成した インスタンスなので、以下の書き方ができる。
require 'optparse'
OptionParser.new {|opt|
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }
opt.parse!(ARGV)
}
p ARGV
この書き方の利点は、
ぐらいか?
optparse.rb を require すると、ARGV に OptionParser::Arguable の機能 が加わる。このことにより、以下の書き方ができるようになる。
require 'optparse'
ARGV.options {|opt|
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }
opt.parse!
}
p ARGV
ruby sample.rb -a foo bar -b baz
# => true
true
["foo", "bar", "baz"]
といった違いがある(そのぐらいの違いしかない?)。
特に利点があるわけではない(と思う)が、optparse 添付のサンプルはこの書 き方になっている。
on() メソッドのオプション定義で末尾に何かを書くと、そのオプション は引数を受け付けることの指定となる。
require 'optparse'
opt = OptionParser.new
opt.on('-a VAL') {|v| p v } # <- " VAL" を追加
opt.on('-b') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb -a foo bar -b baz
# => "foo"
true
["bar", "baz"]
オプションの末尾の書き方の基準は、「ヘルプ の見栄えが良くなるように書く」である。
オプションの引数を省略すると例外 OptionParser::MissingArgument が発生する。
ruby ./sample.rb -a
/usr/local/lib/ruby/1.9/optparse.rb:455:in `parse': missing argument: -a (OptionParser::MissingArgument)
from /usr/local/lib/ruby/1.9/optparse.rb:1295:in `order!'
from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `catch'
from /usr/local/lib/ruby/1.9/optparse.rb:1256:in `order!'
from /usr/local/lib/ruby/1.9/optparse.rb:1336:in `permute!'
from /usr/local/lib/ruby/1.9/optparse.rb:1363:in `parse!'
from ./sample.rb:7
オプションの引数が必須でないことを示すには、" ["(空白+[) を付ける
require 'optparse'
opt = OptionParser.new
opt.on('-a [VAL]') {|v| p v } # <- [VAL] を追加
opt.on('-b') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb -a
# => nil
[]
同様に、ヘルプの見栄えが良いように "VAL]" を付加している。
ロングオプションは、on() の引数に '--'で始まるオプションを指定する。
require 'optparse'
opt = OptionParser.new
opt.on('-a', '--foo') {|v| p v }
opt.on('--bar') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb -a foo bar --bar baz
# => true
true
["foo", "bar", "baz"]
--[no-]...などとすることで、否定型のオプションを指定することができる。
require 'optparse'
opt = OptionParser.new
opt.on('-a', '--foo') {|v| p v }
opt.on('--[no-]bar') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb -a foo bar --bar baz --no-bar
# => true
true
false # <- --no-bar の指定による。
["foo", "bar", "baz"]
オプションに対する引数も指定できる。ショートオプションと同じだが、 GNUの慣習にあわせて
opt.on('-a', '--foo=VAL') {|v| p v }
opt.on('--[no-]bar[=VAL]') {|v| p v }
と "=" を使うのが良いと思われる。
オプションを指定する時は、どのオプションか一意に決まる長さまで指定す れば良い。
require 'optparse'
opt = OptionParser.new
opt.on('-a', '--foo') {|v| p v }
opt.on('--[no-]bar') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby sample.rb --fo
この例では、--fo は、--foo を指定したのと同じになる。この例なら --f まで省略できる。(あまり例がよくない)
デフォルトで、--help と --version オプションを認識する。
ruby ./sample.rb --help # => Usage: sample [options] ruby ./sample.rb --version # => *出力なし*
--version は、トップレベルに Version 定数が定義されていると出力される。 (優先度は低いが VERSION 定数も参照する。Ruby のバージョンを示す VERSION 定数が ruby 1.8 までは定義されているので注意)
require 'optparse' opt = OptionParser.new Version = "1.2.3" # opt.version = "1.2.3" opt.parse!(ARGV) ruby ./sample.rb --version # => sample 1.2.3
on の引数にそのオプションの説明を加えると --help の出力に反映される。
require 'optparse'
opt = OptionParser.new
opt.on('-a', 'description of -a') {|v| p v }
opt.on('-b', 'description of -b') {|v| p v }
opt.parse!(ARGV)
p ARGV
ruby ./sample.rb --help
# => Usage: sample [options]
-a description of -a
-b description of -b
が、1.8.2より前のバージョンではこれだけだとダメらしい。
ruby ./sample.rb --help # => Usage: sample [options]
になる。
opt.on('--help', 'show this message') { puts opt; exit }
をオプション定義に追加するか、ARGVを使った書き方 にする(以下)。
require 'optparse'
ARGV.options {|opt|
opt.on('-a', 'description of -a') {|v| p v }
opt.on('-b', 'description of -b') {|v| p v }
opt.parse!
}
p ARGV
ruby ./sample.rb --help
# => Usage: sample [options]
-a description of -a
-b description of -b