【Ruby】OptionParserを使ってcliツールの引数を制御する

blog.zuckey17.org ↑でRubyに入門して、Ruby学習の一環で簡単なCliツールを作成している時に、引数を簡単に制御したいと思い、OptionParserというライブラリを使った。

メモ的に使い方をまとめておく。

実際のコード

test.rb

#!/usr/bin/env ruby

require "optparse"

params = {}
arguments = []

OptionParser.new do |o|
  o.on("-t", "--title TITLE", "set title param") {|title| params[:title] = title}
  o.on("-b", "--body BODY", "set body param") {|body| params[:body] = body}
  o.on("-h", "--help", "show help") {|| puts HELP_MESSAGE; exit }

  begin
    arguments = o.parse(ARGV)
  rescue OptionParser::InvalidOption => e
    puts e
    exit 1
  end
end

p params
p arguments

今回利用したのは、newというメソッドに対して、ブロックを渡す方法。
newにブロックを渡すとOptionParserオブジェクトを引数にとってブロックが実行される。

実行結果

上記のコードは以下のような実行結果になる。

$ ./test.rb hoge -t タイトル
{:title=>"タイトル"}
["hoge"]

$ ./test.rb hoge -t タイトル -b 本文
{:title=>"タイトル", :body=>"本文"}
["hoge"]

$ ./test.rb -t タイトル -b 本文
{:title=>"タイトル", :body=>"本文"}
[]

$ ./hgoe.rb -t タイトル --b 本文
{:title=>"タイトル", :body=>"本文"}
[]

$ ./test -t タイトル --b 本文 -a zuckey
invalid option: -a

詳しく見てみる

OptionParser#on

引数にオプションとそのオプションの説明を取り、コマンドの引数が与えられたオプションを持っている場合に実行される処理をブロックとして与える。
呼び方は大まかに2パターンで、

# ショートオプションあり
o.on(short, long, description) { |v| puts v }
# ショートオプションなし
o.on(long, description) { |v| puts v }

オプションが引数をとる場合は、-t オプションといったように指定する。
オプションが任意であれば、-t [オプション]とすることで指定が可能。

descriptionは、OptionParser#summaizeメソッド時に表示される。

OptionParser#parse

配列(主にARGV)を与えると、onメソッドで指定した設定の通りにその配列をパースし、オプションとその引数を除外した配列を返す。
そのため、今回の実装では、argumentsにオプション以外の引数が入っていることになる。

onメソッドで指定した以外のオプションを指定した場合、OptionParser::InvalidOptionという例外をが発生するので、良い感じに救ってやる。

begin
  arguments = o.parse(ARGV)
rescue OptionParser::InvalidOption => e
  puts e
  exit 1
end

おわり

あまりRubyコマンドラインツールを作ることはないと思うが、PHPにはあまりこういうライブラリが標準でなかったんじゃないかと思い、面白かったのでまとめておいた。