ただいま整理中。
Blogspot (Blogger?) に移行しました!
タイムライン | 技術系 | TIPS | ライフハック系 | その他 | 左記カテゴリ以外は、右の欄の下のタグクラウドへ!
.

2008年03月16日

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

※[ブックマーク]ボタンの中に delicious, reddit, digg, Google+(G+) のボタンもあります。

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の特徴だ。

一般的には、このようなかたちはプログラミング・ポリシーとしてもオブジェクト指向的にもよろしからざることと思われる。グット・デザイン教会からは破門されるかもしれない。

ただ、ことコマンドライン・オプション処理に限っていえば、この方式はとても楽なのだ; 各オプションとそれらの説明を、一元管理できる。



posted by もふもふ at 05:01 | ロンドン ☁ | Comment(0) | TrackBack(0) | カテゴリ: 仕様・規格 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
トラックバックURLは,"Trackback(x)"のリンクを押すと表示されます.
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。