bar_1

contents_map

ラベル optparse の投稿を表示しています。 すべての投稿を表示
ラベル optparse の投稿を表示しています。 すべての投稿を表示

2014年5月13日火曜日

Ruby OptionParser クラスのリファレンス

ruby 2.0.0-p247 環境で、ri OptionParser | col -bx したものの日本語訳です。
以前 (2008年3月16日)、Ruby: OptionParser (optparse.rb) の使い方 にて、OptionParser の記事を書きましたが、もっと完全なドキュメントが身近にありました。OptionParser のすべての機能について網羅した、こちらの説明のほうがよいでしょう。

OptionParser < Object

(from ruby core)

OptionParser

イントロダクション Introduction

OptionParser はコマンドラインオプション分析のためのクラスです。GetoptLong より、ずっと先進的で、にも関わらず使うのがより簡単、またいっそう Ruby 指向のソリューションです。

仕様 Features

  1. 引数指定とそれを処理するコードは、同じ場所に書かれます。
  2. オプションの要約を出力することができます; この要約文を別々にメンテする必要は、ありません。
  3. 選択的や必須の引数を、非常に優雅に指定されます。
  4. 引数たちを、自動で、指定のクラスに変換することができます。
  5. 引数たちを、適切なセットに制限することができます。
これらの仕様すべて、下記の例にデモしてあります。完全なドキュメントは、#make_switch を見よ。

必要最小限の例 Minimal example

  require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV

完全な記述例 Complete example

下記の例は、完全な Ruby のプログラムです。あなたは実行できますし、さまざまなオプションを指定してみることで、影響をみれます。おそらくこれは optparse の仕様を学ぶのにベストな方法でしょう。
  require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'
class OptparseExample
CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
#
# オプションたちの構造記述を返す。
# Return a structure describing the options.
#
def self.parse(args)
# コマンドラインで指定されたオプションたちは、*options* の中に集められる
# われわれはここではデフォルトの値をセットする。
# The options specified on the command line will be collected in *options*.
# We set default values here.
options = OpenStruct.new
options.library = []
options.inplace = false
options.encoding = "utf8"
options.transfer_type = :auto
options.verbose = false
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.separator ""
opts.separator "Specific options:"
# 必須の引数。
# Mandatory argument.
opts.on("-r", "--require LIBRARY",
"Require the LIBRARY before executing your script") do |lib|
options.library << lib
end
# 選択的な引数; 複数行による記述。
# Optional argument; multi-line description.
opts.on("-i", "--inplace [EXTENSION]",
"Edit ARGV files in place",
"  (make backup if EXTENSION supplied)") do |ext|
options.inplace = true
options.extension = ext || ''
options.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
end
# 引数 'delay' を Float 型に制約する。
# Cast 'delay' argument to a Float.
opts.on("--delay N", Float, "Delay N seconds before executing") do |n|
options.delay = n
end
# 引数 'time' を Time オブジェクトに制限する。
# Cast 'time' argument to a Time object.
opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
options.time = time
end
# 8 進数の整数に制限する。
# Cast to octal integer.
opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
"Specify record separator (default \\0)") do |rs|
options.record_separator = rs
end
# 列挙 (リスト) の引数。
# List of arguments.
opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
options.list = list
end
# キーワード補完。われわれは、特定の引数セットを指定している (CODES
# と CODE_ALIASES - 文字はハッシュであることに注目), そしてユーザは
# もっとも短いあいまいなテキストを使うかもしれない。
# Keyword completion.  We are specifying a specific set of arguments (CODES
# and CODE_ALIASES - notice the latter is a Hash), and the user may provide
# the shortest unambiguous text.
code_list = (CODE_ALIASES.keys + CODES).join(',')
opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
"  (#{code_list})") do |encoding|
options.encoding = encoding
end
# キーワード補完を使った選択的な引数。
# Optional argument with keyword completion.
opts.on("--type [TYPE]", [:text, :binary, :auto],
"Select transfer type (text, binary, auto)") do |t|
options.transfer_type = t
end
# ブーリアン・スイッチ。
# Boolean switch.
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options.verbose = v
end
opts.separator ""
opts.separator "Common options:"
# 引数なしで、tail での表示。これはオプションたちのサマリーをプリントする。
# やってみて!
# No argument, shows at tail.  This will print an options summary.
# Try it and see!
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
# もうひとつの典型的なスイッチ (バージョンを表示)。
# Another typical switch to print the version.
opts.on_tail("--version", "Show version") do
puts OptionParser::Version.join('.')
exit
end
end
opt_parser.parse!(args)
options
end  # parse()
end  # class OptparseExample
options = OptparseExample.parse(ARGV)
pp options
pp ARGV

シェル補完 Shell Completion

For modern shells (e.g. bash, zsh, etc.), you can use shell completion for command line options.
モダンなシェル (e.g. bash, zsh, など) では、コマンドライン・オプションの ためにシェルの補完が使えます。

さらなるドキュメント Further documentation

上述した例はこのクラスをどのように使うかについて学ぶに十分でしょう。もしなんらかの疑問があれば、http://bugs.ruby-lang.org にチケットを切ってください。

定数 Constants:

  • DecimalInteger 10進数整数形式、Integer 型にコンバートするためのもの。
  • DecimalNumeric
    10進数の整数/浮動小数形式、整数を Integer に, 浮動小数を Float に 変換するためのもの。
  • OctalInteger Ruby/C ライクな 8進数/16進数/2進数 整数形式、Integer 型に変換する ためのもの。
  • SPLAT_PROC [not documented]

クラスメソッド Class methods:

  accept
each_const
getopts
inc
new
reject
search_const
show_version
terminate
top
with

インスタンスメソッド Instance methods:

  abort
accept
banner
base
candidate
complete
def_head_option
def_option
def_tail_option
default_argv
define
define_head
define_tail
environment
getopts
help
inc
load
make_switch
new
notwice
on
on_head
on_tail
order
order!
parse
parse!
permute
permute!
program_name
reject
release
remove
search
separator
set_banner
set_program_name
set_summary_indent
set_summary_width
summarize
summary_indent
summary_width
terminate
to_a
to_s
top
ver
version
visit
warn

属性 Attributes:

  attr_accessor default_argv
attr_accessor set_summary_indent
attr_accessor set_summary_width
attr_accessor summary_indent
attr_accessor summary_width
attr_writer banner
attr_writer program_name
attr_writer release
attr_writer set_banner
attr_writer set_program_name
attr_writer version

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の特徴だ。
一般的には、このようなかたちはプログラミング・ポリシーとしてもオブジェクト指向的にもよろしからざることと思われる。グット・デザイン教会からは破門されるかもしれない。
ただ、ことコマンドライン・オプション処理に限っていえば、この方式はとても楽なのだ; 各オプションとそれらの説明を、一元管理できる。