bar_1

contents_map

2008年3月16日日曜日

Ruby: OptionParser (optparse.rb) の使い方

2014-05-13追記: 最新の OptionParser の網羅的機能については、「Ruby OptionParser クラスのリファレンス」 を参照してください。

OptionParser: コマンドライン・オプション解析のためのクラス

コマンドライン・オプションを解析するための方法として、従来からGNU の getopt 系のAPIが使われてきた (Getopt,GetoptLong)。Ruby ではこれらに加えて、optparse.rb の OptionParser クラスを利用する方法があるようだ。
ドキュメントは、たとえば http://stdlib.rubyonrails.org/ などに見つけることができる。
ここでこの OptionParser クラスは、従来の getopt 系クラスと使い勝手がだいぶ違うため、使いにくいという意見が散見される。実際、私も使ってみてその感があった。そこで、リファレンス・ドキュメントから主要な機能を抜き出して、使い方をまとめてみた。

OptionParserクラスの主要な機能および記述の方法

OptionParser は、コマンドラインの配列 ARGV を与えられると、その配列を解析しオプションのタイプに応じた処理を行う。ここで、「オプションのタイプに応じた処理」とは、実際には実装者が作りこむものである。
具体的には以下の3点を記述することになる:
  • オプションの定義
  • 定義されたオプションを指定したときの処理の定義
  • ヘルプ・メッセージの定義
以下にサンプルコードを示す。
#! /usr/bin/ruby
#filename: test-optparse.rb
#author: http://voidptr.seesaa.net
#date: Mar. 11th, 2008
#desc:
#ref.: http://stdlib.rubyonrails.org
#
####
require 'optparse';
require 'ostruct';
require 'pp';
#### Option Parse Method.
def option_parse( args )
#Prepare.
ost         = OpenStruct.new;
#default option values.
#
#
ost.help    = "";
ost.file    = "";
ost.kind    = "";
ost.logfile = "test.log";
ost.verbose = false;
ost.arr     = [];
#
op = OptionParser.new do |opars|
opars.banner = "NAME "+" #{$0} [options]";
opars.separator "";
opars.separator "";
#display -h description at tail of the help message.
#
#
#on_headだと、help表示のとき他のオプションとの間に改行される。
#お好みで。
#opars.on_head( "--version", "show the version." ) do
opars.on( "--version", "show the version." ) do
puts "green 1.0.0";
exit 1;
end
#オペランドありオプション(基本形; オペランドFILEは、必須)
#
#
opars.on( "-f FILE", "specify a file" ) do |f|
ost.file = f;
end
#オペランドありオプション(基本形+; オペランドKINDは必須で、値は選択式・短縮形も可)
#-k a で、-k afterと同じ。-k b で、-k before と同じ意味。
#
#
opars.on( "-k KIND", [:before, :after], "select a kind {before, after}" ) do |k|
ost.kind = k;
end
#オペランドありオプション(基本形++; オペランドは、省略可)
#
#
#
opars.on( "-l [LOGFILE]", "specify the logfile." ) do |l|
if ( l != nil ) then
ost.logfile = l;
end
end
#フラグタイプのオプション (オプションは長い形式もあり; offの形式も同時に定義)
#
#
opars.on( "-v", "--[no-]verbose", "verbose mode switch." ) do |v|
ost.verbose = v;
end
#フラグタイプのオプション
#  on_tail で、オプション定義の〆
#
opars.on_tail( "-t", "--tasukete", "show this message." ) do
puts opars;
exit 1;
end
end  #endof do |opars|.
####
#オプションなしの場合.
#
#
if ( args == [] ) then
#ヘルプを表示。
puts op;
exit 1;
end
#
op.parse!( args );
#必須オプションのチェック
#
#
if ( ost.file == "" ) then
e = OptionParser::ParseError.new;
e.reason = "file was NOT specified (#{ost.file}).";
throw e;
exit 1;
end
#
ost;
end  #endof option_parse
#### Do.
options = option_parse(ARGV)
#### Result.
pp ARGV;
puts "";
pp "Dumper #{options}"
puts "name: #{$0}";
####endof filename: test-optparse.rb

コードについて

OptionParser を newする際に、コード・ブロックを渡している。このコード・ブロック内でオプションの定義、処理、ヘルプメッセージの定義を記述する。
これら3要素は、このコード・ブロック内にすべてまとめて記述することになる —-つまり、ロジックとデータは煮込みすぎたスープのようにどろどろに熔けてしまっている。これは、OptionParserの特徴だ。
一般的には、このようなかたちはプログラミング・ポリシーとしてもオブジェクト指向的にもよろしからざることと思われる。グット・デザイン教会からは破門されるかもしれない。
ただ、ことコマンドライン・オプション処理に限っていえば、この方式はとても楽なのだ; 各オプションとそれらの説明を、一元管理できる。

0 件のコメント:

コメントを投稿

何かありましたら、どうぞ: