本文簡要介紹ruby語言中 OptionParser類
的用法。
OptionParser
OptionParser 的新手?
請參閱 Tutorial 。
介紹
OptionParser
是一個用於命令行選項分析的類。它比 GetoptLong
更先進,但也更易於使用,並且是一個更 Ruby-oriented 的解決方案。
特征
-
參數說明和處理它的代碼寫在同一個地方。
-
它可以輸出一個選項摘要;你不需要單獨維護這個字符串。
-
可選和強製參數的指定非常優雅。
-
參數可以自動轉換為指定的類。
-
參數可以限製在某個集合中。
所有這些函數都在下麵的示例中進行了演示。有關完整文檔,請參閱 make_switch
。
最小的例子
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV
生成幫助
OptionParser
可用於為您編寫的命令自動生成幫助:
require 'optparse'
Options = Struct.new(:name)
class Parser
def self.parse(options)
args = Options.new("world")
opt_parser = OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
args.name = n
end
parser.on("-h", "--help", "Prints this help") do
puts parser
exit
end
end
opt_parser.parse!(options)
return args
end
end
options = Parser.parse %w[--help]
#=>
# Usage: example.rb [options]
# -n, --name=NAME Name to say hello to
# -h, --help Prints this help
必需的參數
對於需要參數的選項,選項規範字符串可能包含全部大寫的選項名稱。如果在沒有所需參數的情況下使用選項,則會引發異常。
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on("-r", "--require LIBRARY",
"Require the LIBRARY before executing your script") do |lib|
puts "You required #{lib}!"
end
end.parse!
用過的:
$ ruby optparse-test.rb -r optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument) $ ruby optparse-test.rb -r my-library You required my-library!
類型強製
OptionParser
支持將命令行參數強製轉換為我們的對象的能力。
OptionParser
帶有一些 ready-to-use 類型的強製轉換。他們是:
-
Date
-Date.parse
接受的任何內容 -
DateTime
-DateTime.parse
接受的任何內容 -
Time
-Time.httpdate
或Time.parse
接受的任何內容 -
URI
-URI.parse
接受的任何內容 -
Shellwords
-Shellwords.shellwords
接受的任何內容 -
String
- 任何非空字符串 -
Integer
- 任何整數。將轉換八進製。 (例如 124、-3、040) -
Float
- 任何浮點數。 (例如 10、3.14、-100E+13) -
Numeric
- 任何整數、浮點數或有理數(1、3.4、1/3) -
DecimalInteger
- 與Integer
類似,但沒有八進製格式。 -
OctalInteger
- 與Integer
類似,但沒有十進製格式。 -
DecimalNumeric
- 十進製整數或浮點數。 -
TrueClass
- 接受‘+, yes, true, -, no, false’,默認為true
-
FalseClass
- 與TrueClass
相同,但默認為false
-
Array
- 以‘,’分隔的字符串(例如 1,2,3) -
Regexp
- 正則表達式。還包括選項。
我們還可以添加我們自己的強製,我們將在下麵介紹。
使用內置轉換
例如,使用內置的Time
轉換。其他內置轉換的行為方式相同。 OptionParser
將嘗試將參數解析為 Time
。如果成功,該時間將傳遞給處理程序塊。否則,將引發異常。
require 'optparse'
require 'optparse/time'
OptionParser.new do |parser|
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
p time
end
end.parse!
用過的:
$ ruby optparse-test.rb -t nonsense ... invalid argument: -t nonsense (OptionParser::InvalidArgument) $ ruby optparse-test.rb -t 10-11-12 2010-11-12 00:00:00 -0500 $ ruby optparse-test.rb -t 9:30 2014-08-13 09:30:00 -0400
創建自定義轉換
OptionParser
上的accept
方法可用於創建轉換器。它指定在指定類時調用哪個轉換塊。下麵的示例使用它在 on
處理程序接收它之前獲取 User
對象。
require 'optparse'
User = Struct.new(:id, :name)
def find_user id
not_found = ->{ raise "No User Found for id #{id}" }
[ User.new(1, "Sam"),
User.new(2, "Gandalf") ].find(not_found) do |u|
u.id == id
end
end
op = OptionParser.new
op.accept(User) do |user_id|
find_user user_id.to_i
end
op.on("--user ID", User) do |user|
puts user
end
op.parse!
用過的:
$ ruby optparse-test.rb --user 1 #<struct User id=1, name="Sam"> $ ruby optparse-test.rb --user 2 #<struct User id=2, name="Gandalf"> $ ruby optparse-test.rb --user 3 optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
將選項存儲到 Hash
order
、parse
等方法的 into
選項將命令行選項存儲到 Hash
中。
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on('-a')
parser.on('-b NUM', Integer)
parser.on('-v', '--verbose')
end.parse!(into: options)
p options
用過的:
$ ruby optparse-test.rb -a {:a=>true} $ ruby optparse-test.rb -a -v {:a=>true, :verbose=>true} $ ruby optparse-test.rb -a -b 100 {:a=>true, :b=>100}
完整示例
下麵的例子是一個完整的 Ruby 程序。您可以運行它並查看指定各種選項的效果。這可能是學習 optparse
函數的最佳方式。
require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'
class OptparseExample
Version = '1.0.0'
CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
class ScriptOptions
attr_accessor :library, :inplace, :encoding, :transfer_type,
:verbose, :extension, :delay, :time, :record_separator,
:list
def initialize
self.library = []
self.inplace = false
self.encoding = "utf8"
self.transfer_type = :auto
self.verbose = false
end
def define_options(parser)
parser.banner = "Usage: example.rb [options]"
parser.separator ""
parser.separator "Specific options:"
# add additional options
perform_inplace_option(parser)
delay_execution_option(parser)
execute_at_time_option(parser)
specify_record_separator_option(parser)
list_example_option(parser)
specify_encoding_option(parser)
optional_option_argument_with_keyword_completion_option(parser)
boolean_verbose_option(parser)
parser.separator ""
parser.separator "Common options:"
# No argument, shows at tail. This will print an options summary.
# Try it and see!
parser.on_tail("-h", "--help", "Show this message") do
puts parser
exit
end
# Another typical switch to print the version.
parser.on_tail("--version", "Show version") do
puts Version
exit
end
end
def perform_inplace_option(parser)
# Specifies an optional option argument
parser.on("-i", "--inplace [EXTENSION]",
"Edit ARGV files in place",
"(make backup if EXTENSION supplied)") do |ext|
self.inplace = true
self.extension = ext || ''
self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
end
end
def delay_execution_option(parser)
# Cast 'delay' argument to a Float.
parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
self.delay = n
end
end
def execute_at_time_option(parser)
# Cast 'time' argument to a Time object.
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
self.time = time
end
end
def specify_record_separator_option(parser)
# Cast to octal integer.
parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
"Specify record separator (default \\0)") do |rs|
self.record_separator = rs
end
end
def list_example_option(parser)
# List of arguments.
parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
self.list = list
end
end
def specify_encoding_option(parser)
# 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(', ')
parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
"(#{code_list})") do |encoding|
self.encoding = encoding
end
end
def optional_option_argument_with_keyword_completion_option(parser)
# Optional '--type' option argument with keyword completion.
parser.on("--type [TYPE]", [:text, :binary, :auto],
"Select transfer type (text, binary, auto)") do |t|
self.transfer_type = t
end
end
def boolean_verbose_option(parser)
# Boolean switch.
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
self.verbose = v
end
end
end
#
# Return a structure describing the options.
#
def parse(args)
# The options specified on the command line will be collected in
# *options*.
@options = ScriptOptions.new
@args = OptionParser.new do |parser|
@options.define_options(parser)
parser.parse!(args)
end
@options
end
attr_reader :parser, :options
end # class OptparseExample
example = OptparseExample.new
options = example.parse(ARGV)
pp options # example.options
pp ARGV
shell Completion
對於現代 shell(例如 bash、zsh 等),您可以將 shell 補全用於命令行選項。
更多文件
上述示例以及隨附的 Tutorial 應該足以學習如何使用此類。如果您有任何問題,請在 bugs.ruby-lang.org 提交票證。
相關用法
- Ruby OptionParser.reject用法及代碼示例
- Ruby OptionParser.getopts用法及代碼示例
- Ruby OptionParser.accept用法及代碼示例
- Ruby Option.level用法及代碼示例
- Ruby Option.byte用法及代碼示例
- Ruby Option.family用法及代碼示例
- Ruby Option.int用法及代碼示例
- Ruby Option.new用法及代碼示例
- Ruby Option.ipv4_multicast_loop用法及代碼示例
- Ruby Option.inspect用法及代碼示例
- Ruby Option.bool用法及代碼示例
- Ruby Option.to_s用法及代碼示例
- Ruby Option.unpack用法及代碼示例
- Ruby Option.optname用法及代碼示例
- Ruby Option.ipv4_multicast_ttl用法及代碼示例
- Ruby Options類用法及代碼示例
- Ruby Option.data用法及代碼示例
- Ruby Option.linger用法及代碼示例
- Ruby Open3.capture3用法及代碼示例
- Ruby Open3.capture2用法及代碼示例
- Ruby OpenStruct.ostruct[name] =用法及代碼示例
- Ruby OpenSSL.fips_mode =用法及代碼示例
- Ruby OpenSSL模塊用法及代碼示例
- Ruby Open3.capture2e用法及代碼示例
- Ruby Open3.popen2e用法及代碼示例
注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 OptionParser類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。