RubyでCLIツールを作ろうと思った時に便利なoptparse
ライブラリですが、意外とまだ知らないことがありました。
OptionParser#on
の引数
基本編
require 'optparse'
opt = OptionParser.new
opt.on('-n', '--name=NAME', 'Your name') do |name|
puts "Your name is #{name}"
end
引数にはショートオプション、ロングオプション、helpメッセージ用の説明文を渡せます。
応用編1
opt.on('--repeat=N', Integer, 'Repeat hello world N times') do |n|
n.times { puts "Hello, world!" }
end
Integer
のようなクラスを渡すと、オプションの引数が適切に変換されて渡ってきます。
上の例で言うと、n.to_i.times
とする必要がありません。
またInteger
を指定したオプションに数字以外を渡すと、ちゃんとエラーを投げてくれます。
他に利用可能なクラスはリファレンスマニュアルを参照してください。
さらに、OptionParser.accept
を使うと自作クラスを引数に渡すこともできます。
応用編2
opt.on('--greeting=GREETING',
/\A(Hello|Good(Morning|Night))\z/, 'Select greeting') do |greeting|
puts "#{greeting}, world!"
end
引数に正規表現を渡すと、それにマッチするオプション引数のみを受け入れます。
上の例で--greeting=Hi
などとするとエラーとなります。
応用編3
opt.on('--greeting=GREETING',
["Hello", "GoodMorning", "GoodNight"], 'Select greeting') do |greeting|
puts "#{greeting}, world!"
end
配列を渡すと、その配列に含まれるもののみをオプションの引数に指定できます。
このコードは正規表現の例と全く同じことを実現しています。
この例だと正規表現はオーバーキルですね。
応用編4
引数にHashを渡すこともできます。
Hashのキーに含まれるもののみをオプションの引数にできるのは配列と同じですが、ブロック引数にHashのvalueを渡してくれます。
以下はシンプルな応用例です。
標準入力からCSV、JSON、YAMLのいずれかを受け取ってRubyのオブジェクトに変換します。
require 'optparse'
require 'csv'
require 'json'
require 'yaml'
AVAILABLE_FORMATS = {
"csv" => CSV.method(:parse),
"json" => JSON.method(:load),
"yaml" => YAML.method(:load)
}
opt = OptionParser.new
opt.on('--format f', AVAILABLE_FORMATS, 'Input format') do |method|
p method.call($stdin.read)
end