以前の記事で、Rubyの標準ライブラリのOptionParserクラスを使ってのコマンドラインオプションをパースする方法について、説明しました。このクラスはかなりよく動作しますが、けっこうくどいです。たった4つのオプションを定義するのに20行そこらのコードが必要になり、理想的ではありません。また、OptionParserクラスの使い方を覚える必要がありますが、いつも使うものではありません。Trollopは、これらの問題を解決する素晴らしいライブラリです。(名前が的を得ているが下品であることを無視すればですが)オプションパーサーを簡単にすることを目的としており邪魔になりません。それは小さい単一のファイルのライブラリです。libライブラリに配置しておくこともできます。コマンドラインオプション1つにつき、1,2行のみのコードを必要とするように目指しており、使用方法を忘れようがないほどです。
Trollopのインストール方法
Trollopは、ネイティブライブラリに依存しない単純なgemです。他のgemと同じようにインストールします。
$ sudo gem install trollop
一旦、インストールしたら、自前のライブラリディレクトリからrequireしたい場合は、trollop.rbをgemsディレクトリからlibディレクトリなどにコピーしてもいいでしょう。また、Trollopのホームページの説明のようにファイルをダウンロードして、Rubygemsを使わない方法もあります。
Trollopの使い方
Trollopの使い方はとても簡単です。はじめにコードで説明した方がいいでしょう。
#!/usr/bin/env ruby
require 'rubygems'
require 'trollop'
# ランダムにtrueかfalseを返す仮のdownloadメソッド
def download( url, user_agent )
[ true, false ][rand(2)]
end
opts = Trollop::options do
opt :url, "URL to download", :required => true
opt :retry, "Retry if download failed", :default => false
opt :delay, "Delay between retries", :default => 15
opt :user_agent, "User Agent string to use", :type => :string
end
while true do
res = download( opts[:url], opts[:user_agent] )
puts "Error" unless res
break if res || !opts[:retry]
sleep opts[:delay]
end
見て分かるようにオプションの全てが(この例では)optsと呼ばれるオブジェクトに格納されています。Trollop::optionsメソッドに渡すブロックの中で簡易なドメイン固有言語(DSL)を定義しています。それぞれのオプションはoptメソッドで定義されています。このメソッドはオプションの名前と短い説明が必須の引数となります。必要であれば、デフォルト値、短形式のオプション、または、(オプション値の)方を引数として渡すことができます。
オプションの定義がオプションパース時であることがこの例で分かると思います。第2段階というものがありません。自動的に定義を取得して、定義を元にしてARGVをパースして、オプションのハッシュを返します。オプションの定義以外、何もする必要がありません。
実際、それぞれのオプションについて6つの定義事項があるだけです。それらは:
- :long - 長形式のオプションを定義します。optメソッドの最初のパラメータが長形式の値となるため必要ありません。
- :short - 単形式のオプションを定義します。このオプションも、オプションの名前から生成されるため必要ありません。
- :type - オプション値の型を定義します。ここでは、:stringや:intを値として使用します。デフォルトでは:flag型となり、オプションには値を取得しません。:defaultオプションを使用した場合は、この:typeオプションは必要ありません。
- :default - ユーザーがオプションを指定しない場合のデフォルト値を定義します。
- :required - ユーザーがオプションを指定しない場合にエラーメッセージを出力して実行停止する場合に定義します。
- :multi - コマンドラインで複数指定されるオプションであることを定義します。例えば、ユーザーは「myprog -f file1 -f file2」と指定できるようになります。
0 件のコメント:
コメントを投稿