getopts -> OptionParser
Rubyでコマンドラインオプションを取り扱うにはどうするのか、調べようと思いました。
(たしかgetoptsという関数があったはず…)
> refe getopts not match: getopts
(あれれ?違ったかしらん。)
> refe opt OpenSSL::SSL::SSLContext#options OpenSSL::SSL::SSLContext#options= OptionParser::Arguable#options OptionParser::Arguable#options= Regexp#options Syslog.options
(ははあ、OptionParserクラスかな)
> refe OptionParser ==== OptionParser ==== optparse.rb optparse::チュートリアル 執筆者募集 コマンドラインのオプションを取り扱うためのクラスです。 オプションが指定された時に呼ばれるブロックを OptionParser#on [OptionParser/on] メソッドで 登録していきます。つまり、 OptionParser を使う場合、基本的には (1) OptionParser オブジェクト opt を生成する。 (2) オプションを取り扱うブロックを opt に登録する。 (3) opt.parse(ARGV) でコマンドラインを実際に parse する。 というような流れになります。 require "optparse" ProgramConfig = Hash.new opts = OptionParser.new opts.on("-a"){|v| ProgramConfig[:a] = true } # -a オプションがコマンドラインで指定されていた場合の動作。 opts.parse!(ARGV) # 実際にコマンドラインの parse を行う。 ...
ふむふむ。onメソッドは「登録」なのですね。
Google先生に聞いてみると、getopts.rb は Ruby 1.8.1 より後では非推奨というのが見つかりました。はあ、そうですか。
では、たとえば、次のようなオプションを理解させてみましょう。
- -d
- -x
require "optparse" ProgramConfig = Hash.new opt = OptionParser.new opt.on("-x") do |f| ProgramConfig[:x] = true end opt.on("-d") do |f| ProgramConfig[:d] = true end opt.parse!(ARGV) ProgramConfig.each_pair do |k,v| puts "#{k} => #{v}" end
動かしてみます。
> ruby a.rb > ruby a.rb -d d => true > ruby a.rb -dx d => true x => true > ruby a.rb -xd d => true x => true > ruby a.rb --help Usage: a [options] -x -d > ruby a.rb -h Usage: a [options] -x -d > ruby a.rb -3 c:/ruby/lib/ruby/1.8/optparse.rb:1445:in `complete': invalid option: -3 (OptionParser::InvalidOption) from c:/ruby/lib/ruby/1.8/optparse.rb:1443:in `complete' from c:/ruby/lib/ruby/1.8/optparse.rb:1302:in `order!' from c:/ruby/lib/ruby/1.8/optparse.rb:1271:in `order!' from c:/ruby/lib/ruby/1.8/optparse.rb:1351:in `permute!' from c:/ruby/lib/ruby/1.8/optparse.rb:1378:in `parse!' from a.rb:11
余談ですが、マニュアルのようなドキュメントでは例が重要だということがよくわかりました。OptionParserのドキュメントも、使い方が書いてあるからすぐに使えるのですね。そういえば、Perlのperldocでも、一番最初にSYNOPSISが出てきます。たいていはここをコピー&ペーストして書き直すと8割方は十分という気がします。
疑問: -d 3とか、値を取るオプションはどうするのかしらん→以下で解決しました。
追記: id:secondlifeさんからopt.on('-d') {|v| p v }というのを教えていただいたのですが、どうもvにはtrueしか来ないようなんです…。
require "optparse" opt = OptionParser.new opt.on("-d") {|v| puts "v=#{v}" } opt.parse!(ARGV)
実行例です。
> ruby a.rb -d 123 v=true
追記: すみません、わたしこそ人に調べさせておりますm(_ _)m id:secondlifeさんありがとうございます。
require "optparse" opt = OptionParser.new opt.on("-d VAL") {|v| puts "v=#{v}" } opt.parse!(ARGV)
実行例です。
> ruby a.rb -d 123 v=123