Spec-Zone.ru › Ruby 2.3

класс OptionParser

Родитель:
Объект

OptionParser

Введение

OptionParser — это класс для анализа опций командной строки. Он намного более продвинутый, но также и проще в использовании, чем GetoptLong, и представляет собой более ориентированное на Ruby решение.

Особенности

  1. Спецификация аргументов и код для их обработки записываются в одном месте.

  2. Он может выводить сводку опций; вам не нужно поддерживать эту строку отдельно.

  3. Необязательные и обязательные аргументы задаются очень изящно.

  4. Аргументы могут быть автоматически преобразованы в указанный класс.

  5. Аргументы могут быть ограничены определённым набором.

Все эти особенности продемонстрированы в примерах ниже. Подробная документация см. в make_switch.

Минимальный пример

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

Генерация справки

OptionParser может использоваться для автоматической генерации справки для команд, которые вы пишете:

require 'optparse'

Options = Struct.new(:name)

class Parser
  def self.parse(options)
    args = Options.new("world")

    opt_parser = OptionParser.new do |opts|
      opts.banner = "Usage: example.rb [options]"

      opts.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
        args.name = n
      end

      opts.on("-h", "--help", "Prints this help") do
        puts opts
        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!

Используется:

bash-3.2$ ruby optparse-test.rb -r
optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
bash-3.2$ ruby optparse-test.rb -r my-library
You required my-library!

Преобразование типов

OptionParser поддерживает возможность принудительного преобразования аргументов командной строки в объекты для нас.

OptionParser поставляется с несколькими готовыми к использованию типами преобразования. Это:

  • Дата – Любое, что принимается Date.parse

  • Дата и время – Любое, что принимается DateTime.parse

  • Время – Любое, что принимается Time.httpdate или Time.parse

  • URI – Любое, что принимается URI.parse

  • Shellwords – Любое, что принимается Shellwords.shellwords

  • Строка – Любая непустая строка

  • Целое число – Любое целое число. Преобразует восьмеричные числа. (например, 124, -3, 040)

  • Вещественное число – Любое вещественное число. (например, 10, 3.14, -100E+13)

  • Числовое – Любое целое число, вещественное число или рациональное число (1, 3.4, 1/3)

  • Десятичное целое число – Как Integer, но без восьмеричного формата.

  • Восьмеричное целое число – Как Integer, но без десятичного формата.

  • Десятичное число – Десятичное целое число или вещественное число.

  • TrueClass – Принимает '+, yes, true, -, no, false' и по умолчанию true

  • FalseClass – Также как TrueClass, но по умолчанию false

  • Массив – Строки, разделённые запятыми (например, 1,2,3)

  • Регулярные выражения – Регулярные выражения. Также включает опции.

Мы также можем добавить свои преобразования, о чём мы поговорим вскоре.

Использование встроенных преобразований

В качестве примера используется встроенное 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!

Используется:

bash-3.2$ ruby optparse-test.rb  -t nonsense
... invalid argument: -t nonsense (OptionParser::InvalidArgument)
from ... time.rb:5:in `block in <top (required)>'
from optparse-test.rb:31:in `<main>'
bash-3.2$ ruby optparse-test.rb  -t 10-11-12
2010-11-12 00:00:00 -0500
bash-3.2$ ruby optparse-test.rb  -t 9:30
2014-08-13 09:30:00 -0400

Создание пользовательских преобразований

Метод accept в OptionParser может использоваться для создания преобразователей. Он определяет, какой блок преобразования вызвать всякий раз, когда указан класс. В приведенном ниже примере используется этот метод для получения объекта User перед тем, как обработчик on получит его.

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!

вывод:

bash-3.2$ ruby optparse-test.rb --user 1
#<struct User id=1, name="Sam">
bash-3.2$ ruby optparse-test.rb --user 2
#<struct User id=2, name="Gandalf">
bash-3.2$ ruby optparse-test.rb --user 3
optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)

Полный пример

Следующий пример — полная программа 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

Оболочка Автозавершение

Для современных оболочек (например, bash, zsh и т. д.) вы можете использовать автозавершение для опций командной строки.

Дополнительная документация

Приведённых выше примеров должно быть достаточно, чтобы понять, как использовать этот класс. Если у вас есть вопросы, создайте запрос на отладку на bugs.ruby-lang.org.

Константы

DecimalInteger

Формат десятичного целого числа, подлежащий преобразованию в Целое.

DecimalNumeric

Формат десятичного целого/вещественного числа, подлежащий преобразованию в Целое для целочисленного формата и Вещественное для формата с плавающей точкой.

OctalInteger

Формат восьмеричного/шестнадцатеричного/двоичного целого числа (типа Ruby/C), подлежащий преобразованию в Целое.

Атрибуты

banner[W]

Заголовок-баннер, предшествующий описанию.

default_argv[RW]

Строки, подлежащие парсингу по умолчанию.

program_name[W]

Имя программы, которое будет выводиться в сообщения об ошибках и по умолчанию в баннере, по умолчанию равно $0.

release[W]

Код выпуска

set_banner[W]

Заголовок-баннер, предшествующий описанию.

set_program_name[W]

Имя программы, которое будет выводиться в сообщения об ошибках и по умолчанию в баннере, по умолчанию равно $0.

set_summary_indent[RW]

Отступ для сводки. Должен быть строкой (или иметь метод + String).

set_summary_width[RW]

Ширина для части списка опций в сводке. Должно быть Числовым.

summary_indent[RW]

Отступ для сводки. Должен быть строкой (или иметь метод + String).

summary_width[RW]

Ширина для части списка опций в сводке. Должно быть Числовым.

version[W]

Версия

Публичные методы класса

accept(*args, &blk) Показать исходный код
# File lib/optparse.rb, line 1099
def self.accept(*args, &blk) top.accept(*args, &blk) end

См. accept.

each_const(path, base = ::Object) Показать исходный код
# File lib/optparse/version.rb, line 50
def each_const(path, base = ::Object)
  path.split(/::|\//).inject(base) do |klass, name|
    raise NameError, path unless Module === klass
    klass.constants.grep(/#{name}/i) do |c|
      klass.const_defined?(c) or next
      klass.const_get(c)
    end
  end
end
getopts(*args) Показать исходный код
# File lib/optparse.rb, line 1691
def self.getopts(*args)
  new.getopts(*args)
end

См. getopts.

inc(arg, default = nil) Показать исходный код
# File lib/optparse.rb, line 1035
def self.inc(arg, default = nil)
  case arg
  when Integer
    arg.nonzero?
  when nil
    default.to_i + 1
  end
end

Возвращает увеличенное значение default в соответствии с arg.

new(banner = nil, width = 32, indent = ' ' * 4) { |self| ... } Показать исходный код
# File lib/optparse.rb, line 1054
def initialize(banner = nil, width = 32, indent = ' ' * 4)
  @stack = [DefaultList, List.new, List.new]
  @program_name = nil
  @banner = banner
  @summary_width = width
  @summary_indent = indent
  @default_argv = ARGV
  add_officious
  yield self if block_given?
end

Инициализирует экземпляр и возвращает его, если вызван с блоком.

banner

Сообщение-баннер.

width

Ширина сводки.

indent

Отступ сводки.

reject(*args, &blk) Показать исходный код
# File lib/optparse.rb, line 1112
def self.reject(*args, &blk) top.reject(*args, &blk) end

См. reject.

search_const(klass, name) { |klass, cname, const| ... } Показать исходный код
# File lib/optparse/version.rb, line 60
def search_const(klass, name)
  klasses = [klass]
  while klass = klasses.shift
    klass.constants.each do |cname|
      klass.const_defined?(cname) or next
      const = klass.const_get(cname)
      yield klass, cname, const if name === cname
      klasses << const if Module === const and const != ::Object
    end
  end
end
show_version(*pkgs) Показать исходный код
# File lib/optparse/version.rb, line 5
def show_version(*pkgs)
  progname = ARGV.options.program_name
  result = false
  show = proc do |klass, cname, version|
    str = "#{progname}"
    unless klass == ::Object and cname == :VERSION
      version = version.join(".") if Array === version
      str << ": #{klass}" unless klass == Object
      str << " version #{version}"
    end
    [:Release, :RELEASE].find do |rel|
      if klass.const_defined?(rel)
        str << " (#{klass.const_get(rel)})"
      end
    end
    puts str
    result = true
  end
  if pkgs.size == 1 and pkgs[0] == "all"
    self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version|
      unless cname[1] == ?e and klass.const_defined?(:Version)
        show.call(klass, cname.intern, version)
      end
    end
  else
    pkgs.each do |pkg|
      begin
        pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
        v = case
            when pkg.const_defined?(:Version)
              pkg.const_get(n = :Version)
            when pkg.const_defined?(:VERSION)
              pkg.const_get(n = :VERSION)
            else
              n = nil
              "unknown"
            end
        show.call(pkg, n, v)
      rescue NameError
      end
    end
  end
  result
end
terminate(arg = nil) Показать исходный код
# File lib/optparse.rb, line 1079
def self.terminate(arg = nil)
  throw :terminate, arg
end
top() Показать исходный код
# File lib/optparse.rb, line 1084
def self.top() DefaultList end
with(*args, &block) Показать исходный код
# File lib/optparse.rb, line 1026
def self.with(*args, &block)
  opts = new(*args)
  opts.instance_eval(&block)
  opts
end

Инициализирует новый экземпляр и вычисляет необязательный блок в контексте экземпляра. Аргументы args передаются в new, см. там описание параметров.

Этот метод устарел; его поведение соответствует более старому методу new.

Публичные методы экземпляра

abort(mesg = $!) Показать исходный код
# File lib/optparse.rb, line 1193
def abort(mesg = $!)
  super("#{program_name}: #{mesg}")
end
Вызывает метод суперкласса Kernel#abort
accept(*args, &blk) Показать исходный код
# File lib/optparse.rb, line 1095
def accept(*args, &blk) top.accept(*args, &blk) end

Направляет на принятие указанного класса t. Строка аргумента передаётся в блок, в котором она должна быть преобразована к желаемому классу.

t

Указатель класса аргумента, любой объект, включая Class.

pat

Шаблон для аргумента, по умолчанию t , если он отвечает методу match.

accept(t, pat, &block)
banner() Показать исходный код
# File lib/optparse.rb, line 1137
def banner
  unless @banner
    @banner = "Usage: #{program_name} [options]"
    visit(:add_banner, @banner)
  end
  @banner
end

Заголовок, предшествующий описанию.

base() Показать исходный код
# File lib/optparse.rb, line 1207
def base
  @stack[1]
end

Объект метода on_tail.

candidate(word) Показать исходный код
# File lib/optparse.rb, line 1738
def candidate(word)
  list = []
  case word
  when /\A--/
    word, arg = word.split(/=/, 2)
    argpat = Completion.regexp(arg, false) if arg and !arg.empty?
    long = true
  when /\A-(!-)/
    short = true
  when /\A-/
    long = short = true
  end
  pat = Completion.regexp(word, true)
  visit(:each_option) do |opt|
    next unless Switch === opt
    opts = (long ? opt.long : []) + (short ? opt.short : [])
    opts = Completion.candidate(word, true, pat, &opts.method(:each)).map(&:first) if pat
    if /\A=/ =~ opt.arg
      opts.map! {|sw| sw + "="}
      if arg and CompletingHash === opt.pattern
        if opts = opt.pattern.candidate(arg, false, argpat)
          opts.map!(&:last)
        end
      end
    end
    list.concat(opts)
  end
  list
end
def_head_option(*opts, &block)
Псевдоним для: define_head
def_option(*opts, &block)
Псевдоним для: define
def_tail_option(*opts, &block)
Псевдоним для: define_tail
define(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1462
def define(*opts, &block)
  top.append(*(sw = make_switch(opts, block)))
  sw[0]
end
Также псевдоним: def_option
define_head(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1477
def define_head(*opts, &block)
  top.prepend(*(sw = make_switch(opts, block)))
  sw[0]
end
Также псевдоним: def_head_option
define_tail(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1491
def define_tail(*opts, &block)
  base.append(*(sw = make_switch(opts, block)))
  sw[0]
end
Также псевдоним: def_tail_option
environment(env = File.basename($0, '.*')) Показать исходный код
# File lib/optparse.rb, line 1795
def environment(env = File.basename($0, '.*'))
  env = ENV[env] || ENV[env.upcase] or return
  require 'shellwords'
  parse(*Shellwords.shellwords(env))
end

Парсит переменную окружения env или её верхний регистр с разделением, как в оболочке.

env по умолчанию является основой имени программы.

getopts(*args) Показать исходный код
# File lib/optparse.rb, line 1656
def getopts(*args)
  argv = Array === args.first ? args.shift : default_argv
  single_options, *long_options = *args

  result = {}

  single_options.scan(/(.)(:)?/) do |opt, val|
    if val
      result[opt] = nil
      define("-#{opt} VAL")
    else
      result[opt] = false
      define("-#{opt}")
    end
  end if single_options

  long_options.each do |arg|
    arg, desc = arg.split(';', 2)
    opt, val = arg.split(':', 2)
    if val
      result[opt] = val.empty? ? nil : val
      define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
    else
      result[opt] = false
      define("--#{opt}", *[desc].compact)
    end
  end

  parse_in_order(argv, result.method(:[]=))
  result
end

Метод-обёртка для getopts.rb.

params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option)
# params[:a] = true   # -a
# params[:b] = "1"    # -b1
# params[:foo] = "1"  # --foo
# params[:bar] = "x"  # --bar x
# params[:zot] = "z"  # --zot Z
help() Показать исходный код
# File lib/optparse.rb, line 1248
def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end

Возвращает строку с описанием параметров.

Также псевдоним: to_s
inc(*args) Показать исходный код
# File lib/optparse.rb, line 1043
def inc(*args)
  self.class.inc(*args)
end
load(filename = nil) Показать исходный код
# File lib/optparse.rb, line 1775
def load(filename = nil)
  begin
    filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')
  rescue
    return false
  end
  begin
    parse(*IO.readlines(filename).each {|s| s.chomp!})
    true
  rescue Errno::ENOENT, Errno::ENOTDIR
    false
  end
end

Загружает параметры из файлов как filename. Не выполняет никаких действий, если файл отсутствует. Возвращает, загружался ли он успешно.

filename по умолчанию является основой имени программы без суффикса в каталоге ~/.options.

make_switch(opts, block = nil) Показать исходный код
# File lib/optparse.rb, line 1332
def make_switch(opts, block = nil)
  short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
  ldesc, sdesc, desc, arg = [], [], []
  default_style = Switch::NoArgument
  default_pattern = nil
  klass = nil
  q, a = nil
  has_arg = false

  opts.each do |o|
    # argument class
    next if search(:atype, o) do |pat, c|
      klass = notwice(o, klass, 'type')
      if not_style and not_style != Switch::NoArgument
        not_pattern, not_conv = pat, c
      else
        default_pattern, conv = pat, c
      end
    end

    # directly specified pattern(any object possible to match)
    if (!(String === o || Symbol === o)) and o.respond_to?(:match)
      pattern = notwice(o, pattern, 'pattern')
      if pattern.respond_to?(:convert)
        conv = pattern.method(:convert).to_proc
      else
        conv = SPLAT_PROC
      end
      next
    end

    # anything others
    case o
    when Proc, Method
      block = notwice(o, block, 'block')
    when Array, Hash
      case pattern
      when CompletingHash
      when nil
        pattern = CompletingHash.new
        conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
      else
        raise ArgumentError, "argument pattern given twice"
      end
      o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
    when Module
      raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
    when *ArgumentStyle.keys
      style = notwice(ArgumentStyle[o], style, 'style')
    when /^--no-([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      not_pattern, not_conv = search(:atype, o) unless not_style
      not_style = (not_style || default_style).guess(arg = a) if a
      default_style = Switch::NoArgument
      default_pattern, conv = search(:atype, FalseClass) unless default_pattern
      ldesc << "--no-#{q}"
      long << 'no-' + (q = q.downcase)
      nolong << q
    when /^--\[no-\]([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--[no-]#{q}"
      long << (o = q.downcase)
      not_pattern, not_conv = search(:atype, FalseClass) unless not_style
      not_style = Switch::NoArgument
      nolong << 'no-' + o
    when /^--([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--#{q}"
      long << (o = q.downcase)
    when /^-(\[\^?\]?(?:[^\\]]|\.)*\])(.+)?/
      q, a = $1, $2
      o = notwice(Object, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      else
        has_arg = true
      end
      sdesc << "-#{q}"
      short << Regexp.new(q)
    when /^-(.)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      sdesc << "-#{q}"
      short << q
    when /^=/
      style = notwice(default_style.guess(arg = o), style, 'style')
      default_pattern, conv = search(:atype, Object) unless default_pattern
    else
      desc.push(o)
    end
  end

  default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
  if !(short.empty? and long.empty?)
    if has_arg and default_style == Switch::NoArgument
      default_style = Switch::RequiredArgument
    end
    s = (style || default_style).new(pattern || default_pattern,
                                     conv, sdesc, ldesc, arg, desc, block)
  elsif !block
    if style or pattern
      raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
    end
    s = desc
  else
    short << pattern
    s = (style || default_style).new(pattern,
                                     conv, nil, nil, arg, desc, block)
  end
  return s, short, long,
    (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
    nolong
end

Создаёт OptionParser::Switch из параметров. Значение обработанного аргумента передаётся в указанный блок, где он может быть обработан.

См. в начале OptionParser для примеров.

opts может содержать следующие элементы:

Стиль аргумента:

Один из следующих:

:NONE, :REQUIRED, :OPTIONAL
Шаблон аргумента:

Допустимый формат аргумента команды, должен быть предварительно определён с помощью #accept или #accept, или Regexp. Может появиться один раз или быть задан как Строка, если отсутствует, иначе вызывает ArgumentError. Примеры:

Float, Time, Array
Возможные значения аргумента:

Hash или Массив.

[:text, :binary, :auto]
%w[iso-2022-jp shift_jis euc-jp utf8 binary]
{ "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
Переключатель длинного стиля:

Указывает переключатель длинного стиля, который принимает обязательный, необязательный или отсутствие аргумента. Это строка следующего формата:

"--switch=MANDATORY" or "--switch MANDATORY"
"--switch[=OPTIONAL]"
"--switch"
Переключатель короткого стиля:

Указывает переключатель короткого стиля, который принимает обязательный, необязательный или отсутствие аргумента. Это строка следующего формата:

"-xMANDATORY"
"-x[OPTIONAL]"
"-x"

Также существует специальная форма, которая соответствует диапазону символов (не полный набор регулярных выражений):

"-[a-z]MANDATORY"
"-[a-z][OPTIONAL]"
"-[a-z]"
Стиль аргумента и описание:

Вместо непосредственного указания обязательных или необязательных аргументов в параметре переключателя, можно использовать этот отдельный параметр.

"=MANDATORY"
"=[OPTIONAL]"
Описание:

Строка описания параметра.

"Run verbosely"
Обработчик:

Обработчик для значения обработанного аргумента. Либо укажите блок, либо передайте Proc или Method в качестве аргумента.

new() { |self| ... } Показать исходный код
# File lib/optparse.rb, line 1214
def new
  @stack.push(List.new)
  if block_given?
    yield self
  else
    self
  end
end

Добавляет новый список.

on(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1471
def on(*opts, &block)
  define(*opts, &block)
  self
end

Добавить переключатель параметра и обработчик. См. make_switch для объяснения параметров.

on_head(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1485
def on_head(*opts, &block)
  define_head(*opts, &block)
  self
end

Добавить переключатель параметра как с on, но в начале сводки.

on_tail(*opts, &block) Показать исходный код
# File lib/optparse.rb, line 1499
def on_tail(*opts, &block)
  define_tail(*opts, &block)
  self
end

Добавить переключатель параметра как с on, но в конце сводки.

order(*argv, &block) Показать исходный код
# File lib/optparse.rb, line 1518
def order(*argv, &block)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  order!(argv, &block)
end

Парсит аргументы командной строки argv в порядке их следования. Если блок задан, каждый аргумент, не являющийся опцией, возвращается.

Возвращает оставшуюся часть argv необработанных аргументов.

order!(argv = default_argv, &nonopt) Показать исходный код
# File lib/optparse.rb, line 1527
def order!(argv = default_argv, &nonopt)
  parse_in_order(argv, &nonopt)
end

Аналогично order, но удаляет переключатели деструктивно. Аргументы, не являющиеся опциями, остаются в argv.

parse(*argv) Показать исходный код
# File lib/optparse.rb, line 1629
def parse(*argv)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  parse!(argv)
end

Парсит аргументы командной строки argv в порядке их следования, когда переменная окружения POSIXLY_CORRECT установлена, и в режиме перестановки в противном случае.

parse!(argv = default_argv) Показать исходный код
# File lib/optparse.rb, line 1638
def parse!(argv = default_argv)
  if ENV.include?('POSIXLY_CORRECT')
    order!(argv)
  else
    permute!(argv)
  end
end

Аналогично parse, но удаляет переключатели деструктивно. Аргументы, не являющиеся опциями, остаются в argv.

permute(*argv) Показать исходный код
# File lib/optparse.rb, line 1609
def permute(*argv)
  argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  permute!(argv)
end

Парсит аргументы командной строки argv в режиме перестановки и возвращает список аргументов, не являющихся опциями.

permute!(argv = default_argv) Показать исходный код
# File lib/optparse.rb, line 1618
def permute!(argv = default_argv)
  nonopts = []
  order!(argv, &nonopts.method(:<<))
  argv[0, 0] = nonopts
  argv
end

Аналогично permute, но удаляет переключатели деструктивно. Аргументы, не являющиеся опциями, остаются в argv.

program_name() Показать исходный код
# File lib/optparse.rb, line 1149
def program_name
  @program_name || File.basename($0, '.*')
end

Имя программы, которое будет отображаться в сообщениях об ошибках и стандартном баннере, по умолчанию равно $0.

reject(*args, &blk) Показать исходный код
# File lib/optparse.rb, line 1108
def reject(*args, &blk) top.reject(*args, &blk) end

Направляет отказ на указанный аргумент класса.

t

Указатель класса аргумента, любой объект, включая Класс.

reject(t)
release() Показать исходный код
# File lib/optparse.rb, line 1174
def release
  @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
end

Код выпуска

remove() Показать исходный код
# File lib/optparse.rb, line 1226
def remove
  @stack.pop
end

Удаляет последний список.

separator(string) Показать исходный код
# File lib/optparse.rb, line 1508
def separator(string)
  top.append(string, nil, nil)
end

Добавляет разделитель в сводку.

summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk) Показать исходный код
# File lib/optparse.rb, line 1239
def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
  blk ||= proc {|l| to << (l.index($/, -1) ? l : l + $/)}
  visit(:summarize, {}, {}, width, max, indent, &blk)
  to
end

Выводит сводку опций в to и возвращает to. Если указан блок, возвращает каждую строку.

to

Место назначения вывода, которое должно иметь метод <<. По умолчанию [].

width

Ширина левой части, по умолчанию @summary_width.

max

Максимальная длина, разрешенная для левой части, по умолчанию width - 1.

indent

Отступ, по умолчанию @summary_indent.

terminate(arg = nil) Показать исходный код
# File lib/optparse.rb, line 1076
def terminate(arg = nil)
  self.class.terminate(arg)
end

Прерывает разбор опций. Необязательный параметр arg — строка, которая возвращается в качестве первого аргумента, не являющегося опцией.

to_a() Показать исходный код
# File lib/optparse.rb, line 1254
def to_a; summarize("#{banner}".split(/^/)) end

Возвращает список сводки опций.

to_s()
Псевдоним для: help
top() Показать исходный код
# File lib/optparse.rb, line 1200
def top
  @stack[-1]
end

Объект on / on_head, accept / reject

ver() Показать исходный код
# File lib/optparse.rb, line 1181
def ver
  if v = version
    str = "#{program_name} #{[v].join('.')}"
    str << " (#{v})" if v = release
    str
  end
end

Возвращает строку версии из #program_name, версии и выпуска.

version() Показать исходный код
# File lib/optparse.rb, line 1167
def version
  @version || (defined?(::Version) && ::Version)
end

Версия

warn(mesg = $!) Показать исходный код
# File lib/optparse.rb, line 1189
def warn(mesg = $!)
  super("#{program_name}: #{mesg}")
end
Вызывает метод суперкласса Kernel#warn

Приватные методы экземпляра

complete(typ, opt, icase = false, *pat) Показать исходный код
# File lib/optparse.rb, line 1727
def complete(typ, opt, icase = false, *pat)
  if pat.empty?
    search(typ, opt) {|sw| return [sw, opt]} # exact match or...
  end
  raise AmbiguousOption, catch(:ambiguous) {
    visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
    raise InvalidOption, opt
  }
end

Завершает сокращённый вариант переключателя стиля длинного варианта и возвращает пару канонического переключателя и описания переключателя OptionParser::Switch.

typ

Таблица поиска.

opt

Ключ поиска.

icase

Производить поиск без учёта регистра, если значение true.

pat

Необязательный шаблон для завершения.

notwice(obj, prv, msg) Показать исходный код
# File lib/optparse.rb, line 1264
def notwice(obj, prv, msg)
  unless !prv or prv == obj
    raise(ArgumentError, "argument #{msg} given twice: #{obj}",
          ParseError.filter_backtrace(caller(2)))
  end
  obj
end

Проверяет, задан ли аргумент дважды. В случае, если да, то генерируется исключение ArgumentError. Вызывается только из OptionParser#switch.

obj

Новый аргумент.

prv

Предыдущий указанный аргумент.

msg

Сообщение об ошибке (исключение).

search(id, key) { |k| ... } Показать исходный код
# File lib/optparse.rb, line 1710
def search(id, key)
  block_given = block_given?
  visit(:search, id, key) do |k|
    return block_given ? yield(k) : k
  end
end

Ищет key в @stack для хэша id и возвращает или возвращает результат.

visit(id, *args, &block) Показать исходный код
# File lib/optparse.rb, line 1699
def visit(id, *args, &block)
  @stack.reverse_each do |el|
    el.send(id, *args, &block)
  end
  nil
end

Проходит по @stack, отправляя каждому элементу метод id со значениями args и block.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API