當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Ruby OptionParser類用法及代碼示例


本文簡要介紹ruby語言中 OptionParser類 的用法。

OptionParser

OptionParser 的新手?

請參閱 Tutorial

介紹

OptionParser 是一個用於命令行選項分析的類。它比 GetoptLong 更先進,但也更易於使用,並且是一個更 Ruby-oriented 的解決方案。

特征

  1. 參數說明和處理它的代碼寫在同一個地方。

  2. 它可以輸出一個選項摘要;你不需要單獨維護這個字符串。

  3. 可選和強製參數的指定非常優雅。

  4. 參數可以自動轉換為指定的類。

  5. 參數可以限製在某個集合中。

所有這些函數都在下麵的示例中進行了演示。有關完整文檔,請參閱 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.httpdateTime.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

orderparse 等方法的 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-lang.org大神的英文原創作品 OptionParser類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。