Spec-Zone.ru › Elixir 1.4

OptionParser

Этот модуль содержит функции для разбора командной строки.

Краткое описание

Типы

argv()
errors()
options()
parsed()

Функции

get_option_key(option, allow_nonexistent_atoms?)
next(argv, opts \\ [])

Функция низкого уровня, которая анализирует один параметр.

parse(argv, opts \\ [])

Анализирует argv в список ключевых слов.

parse!(argv, opts \\ [])

То же самое, что и parse/2, но вызывает исключение OptionParser.ParseError, если заданы какие-либо недопустимые параметры.

parse_head(argv, opts \\ [])

Аналогично parse/2, но анализирует только начало argv; как только находит параметр, не являющийся переключателем, прекращает анализ.

parse_head!(argv, opts \\ [])

То же самое, что и parse_head/2, но вызывает исключение OptionParser.ParseError, если заданы какие-либо недопустимые параметры.

split(string)

Разделяет строку на фрагменты argv/0.

to_argv(enum, opts \\ [])

Принимает перечислимое значение ключ-значение и преобразует его в argv/0.

Типы

argv()

argv() :: [String.t()]

errors()

errors() :: [{String.t(), String.t() | nil}]

options()

options() :: [switches: Keyword.t(), strict: Keyword.t(), aliases: Keyword.t()]

parsed()

parsed() :: Keyword.t()

Функции

get_option_key(option, allow_nonexistent_atoms?)

next(argv, opts \\ [])

next(argv(), options()) ::
  {:ok, key :: atom(), value :: term(), argv()} |
  {:invalid, String.t(), String.t() | nil, argv()} |
  {:undefined, String.t(), String.t() | nil, argv()} |
  {:error, argv()}

Функция низкого уровня, которая анализирует один параметр.

Она принимает те же параметры, что и parse/2 и parse_head/2, так как обе функции построены на основе этой функции. Эта функция может возвращать:

  • {:ok, key, value, rest} - параметр key с value был успешно проанализирован

  • {:invalid, key, value, rest} - параметр key недействителен с value (возвращается, когда значение не может быть проанализировано в соответствии с типом переключателя)

  • {:undefined, key, value, rest} - параметр key не определен (возвращается в строгом режиме, когда переключатель неизвестен)

  • {:error, rest} - нет переключателей в начале заданного argv

parse(argv, opts \\ [])

parse(argv(), options()) :: {parsed(), argv(), errors()}

Анализирует argv в список ключевых слов.

Она возвращает кортеж из трёх элементов вида {parsed, args, invalid}, где:

  • parsed — это список проанализированных переключателей с кортежами {switch_name, value} в нём; switch_name — это атом, представляющий имя переключателя, а value — это значение для этого переключателя, проанализированное в соответствии с opts (подробнее см. раздел «Примеры»)
  • args — это список оставшихся аргументов в argv в виде строк
  • invalid — это список недопустимых параметров в виде {option_name, value}, где option_name — исходный параметр, а value — nil если параметр не ожидался или строковое значение, если значение не имело ожидаемого типа для соответствующего параметра

Elixir преобразует переключатели в атомы с нижним подчеркиванием, поэтому --source-path становится :source_path. Это сделано для лучшей совместимости с соглашениями Elixir. Однако это означает, что переключатели не могут содержать нижние подчеркивания, а переключатели, содержащие нижние подчеркивания, всегда возвращаются в списке недопустимых переключателей.

При анализе полезно перечислить переключатели и их ожидаемые типы:

iex> OptionParser.parse(["--debug"], switches: [debug: :boolean])
{[debug: true], [], []}

iex> OptionParser.parse(["--source", "lib"], switches: [source: :string])
{[source: "lib"], [], []}

iex> OptionParser.parse(["--source-path", "lib", "test/enum_test.exs", "--verbose"],
...>                    switches: [source_path: :string, verbose: :boolean])
{[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}

Ниже мы рассмотрим допустимые переключатели и режимы работы парсера опций.

Параметры

Поддерживаются следующие параметры:

  • :switches или :strict - см. раздел «Определения переключателей» ниже
  • :allow_nonexistent_atoms - см. раздел «Анализ динамических переключателей» ниже
  • :aliases - см. раздел «Псевдонимы» ниже

Определения переключателей

Переключатели можно указать с помощью одного из двух вариантов:

  • :switches - определяет некоторые переключатели и их типы. Эта функция по-прежнему пытается проанализировать переключатели, которые не находятся в этом списке.
  • :strict - определяет строгие переключатели. Любой переключатель в argv , который не указан в списке, возвращается в списке недопустимых параметров.

Оба этих параметра принимают список ключевых слов кортежей {name, type}, где name — атом, определяющий имя переключателя, и type — атом, определяющий тип значения этого переключателя (см. раздел «Типы» ниже для возможных типов и дополнительной информации о приведении типов).

Обратите внимание, что вы должны использовать только параметр :switches или :strict. Если вы укажете оба, будет возбуждено исключение ArgumentError.

Типы

Переключатели, проанализированные функцией OptionParser, могут принимать ноль или один аргумент.

Следующие типы переключателей не принимают аргументов:

  • :boolean - устанавливает значение в true при наличии (см. также раздел «Отрицающие переключатели» ниже)
  • :count - подсчитывает количество раз, когда переключатель задан

Следующие переключатели принимают один аргумент:

  • :integer - анализирует значение как целое число
  • :float - анализирует значение как число с плавающей точкой
  • :string - анализирует значение как строку

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

Модификаторы

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

  • :keep - сохраняет дублированные элементы вместо их перезаписи; работает со всеми типами, кроме :count. Указание switch_name: :keep предполагает, что тип :switch_name будет :string.

Чтобы использовать :keep с типом, отличным от :string, используйте список в качестве типа переключателя. Например: [foo: [:integer, :keep]].

Отрицающие переключатели

Если переключатель SWITCH указан с типом :boolean, его можно передать и как --no-SWITCH, что установит параметр в значение false:

iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean])
{[op: false], ["path/to/file"], []}

Анализ динамических переключателей

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

iex> OptionParser.parse(["--debug"])
{[debug: true], [], []}

Переключатели, за которыми следует значение, будут назначены это значение как строку. Переключатели без аргумента, например, --debug в примерах выше, автоматически будут установлены в значение true.

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

OptionParser.parse(["--option-parser-example"])
# Does nothing more...

Однако, следующий код выполняется, так как атом :option_parser_example используется где-то позже (или раньше):

{opts, _, _} = OptionParser.parse(["--option-parser-example"])
opts[:option_parser_example]

Другими словами, при использовании динамического режима Elixir будет правильно анализировать только те параметры, которые используются во время выполнения, игнорируя все остальные. Если вы хотите проанализировать все переключатели, независимо от их существования, вы можете принудительно создать атомы, передав allow_nonexistent_atoms: true в качестве параметра. Такой параметр полезен при создании командных приложений, которые получают динамически названные аргументы, но следует использовать с осторожностью в долго работающих системах.

Переключатели, за которыми следует значение, будут назначены это значение как строку. Переключатели без аргумента, например, --debug в примерах выше, автоматически будут установлены в значение true.

Псевдонимы

Список псевдонимов можно указать в параметре :aliases:

iex> OptionParser.parse(["-d"], aliases: [d: :debug])
{[debug: true], [], []}

Примеры

Ниже приведены примеры работы с различными типами и модификаторами:

iex> OptionParser.parse(["--unlock", "path/to/file"], strict: [unlock: :boolean])
{[unlock: true], ["path/to/file"], []}

iex> OptionParser.parse(["--unlock", "--limit", "0", "path/to/file"],
...>                    strict: [unlock: :boolean, limit: :integer])
{[unlock: true, limit: 0], ["path/to/file"], []}

iex> OptionParser.parse(["--limit", "3"], strict: [limit: :integer])
{[limit: 3], [], []}

iex> OptionParser.parse(["--limit", "xyz"], strict: [limit: :integer])
{[], [], [{"--limit", "xyz"}]}

iex> OptionParser.parse(["--verbose"], switches: [verbose: :count])
{[verbose: 1], [], []}

iex> OptionParser.parse(["-v", "-v"], aliases: [v: :verbose], strict: [verbose: :count])
{[verbose: 2], [], []}

iex> OptionParser.parse(["--unknown", "xyz"], strict: [])
{[], ["xyz"], [{"--unknown", nil}]}

iex> OptionParser.parse(["--limit", "3", "--unknown", "xyz"],
...>                    switches: [limit: :integer])
{[limit: 3, unknown: "xyz"], [], []}

iex> OptionParser.parse(["--unlock", "path/to/file", "--unlock", "path/to/another/file"], strict: [unlock: :keep])
{[unlock: "path/to/file", unlock: "path/to/another/file"], [], []}

parse!(argv, opts \\ [])

parse!(argv(), options()) :: {parsed(), argv()} | no_return()

То же самое, что и parse/2, но вызывает исключение OptionParser.ParseError, если заданы какие-либо недопустимые параметры.

Если ошибок нет, возвращается кортеж {parsed, rest}, где:

  • parsed — список проанализированных переключателей (аналогично parse/2)
  • rest — список аргументов (аналогично parse/2)

Примеры

iex> OptionParser.parse!(["--debug", "path/to/file"], strict: [debug: :boolean])
{[debug: true], ["path/to/file"]}

iex> OptionParser.parse!(["--limit", "xyz"], strict: [limit: :integer])
** (OptionParser.ParseError) 1 error found!
--limit : Expected type integer, got "xyz"

iex> OptionParser.parse!(["--unknown", "xyz"], strict: [])
** (OptionParser.ParseError) 1 error found!
--unknown : Unknown option

iex> OptionParser.parse!(["-l", "xyz", "-f", "bar"],
...>                     switches: [limit: :integer, foo: :integer], aliases: [l: :limit, f: :foo])
** (OptionParser.ParseError) 2 errors found!
-l : Expected type integer, got "xyz"
-f : Expected type integer, got "bar"

parse_head(argv, opts \\ [])

parse_head(argv(), options()) :: {parsed(), argv(), errors()}

Аналогично parse/2, но анализирует только заголовок argv; как только обнаруживает элемент, не являющийся переключателем, прекращает анализ.

Дополнительную информацию см. в parse/2.

Пример

iex> OptionParser.parse_head(["--source", "lib", "test/enum_test.exs", "--verbose"],
...>                         switches: [source: :string, verbose: :boolean])
{[source: "lib"], ["test/enum_test.exs", "--verbose"], []}

iex> OptionParser.parse_head(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
...>                         switches: [source: :string, verbose: :boolean, unlock: :boolean])
{[verbose: true, source: "lib"], ["test/enum_test.exs", "--unlock"], []}

parse_head!(argv, opts \\ [])

parse_head!(argv(), options()) :: {parsed(), argv()} | no_return()

То же, что и parse_head/2, но при наличии некорректных параметров выбрасывает исключение OptionParser.ParseError.

В случае отсутствия ошибок возвращает кортеж {parsed, rest}, где:

  • parsed — список проанализированных переключателей (аналогично parse_head/2)
  • rest — список аргументов (аналогично parse_head/2)

Примеры

iex> OptionParser.parse_head!(["--source", "lib", "path/to/file", "--verbose"],
...>                         switches: [source: :string, verbose: :boolean])
{[source: "lib"], ["path/to/file", "--verbose"]}

iex> OptionParser.parse_head!(["--number", "lib", "test/enum_test.exs", "--verbose"],
...>                          strict: [number: :integer])
** (OptionParser.ParseError) 1 error found!
--number : Expected type integer, got "lib"

iex> OptionParser.parse_head!(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
...>                          strict: [verbose: :integer, source: :integer])
** (OptionParser.ParseError) 2 errors found!
--verbose : Missing argument of type integer
--source : Expected type integer, got "lib"

split(string)

split(String.t()) :: argv()

Разбивает строку на фрагменты argv/0.

Данная функция разбивает заданную string строку на список строк аналогично многим оболочкам.

Примеры

iex> OptionParser.split("foo bar")
["foo", "bar"]

iex> OptionParser.split("foo \"bar baz\"")
["foo", "bar baz"]

to_argv(enum, opts \\ [])

to_argv(Enumerable.t(), options()) :: argv()

Принимает перечислимое значение с парами ключ-значение и преобразует его в argv/0.

Ключи должны быть атомами. Ключи со значением nil игнорируются, булевы значения преобразуются в --key или --no-key (если значение соответственно равно true или false ), а все остальные значения преобразуются с помощью Kernel.to_string/1.

Рекомендуется передавать в to_argv/2 тот же набор options параметров, что и в parse/2. Некоторые переключатели могут быть корректно реконструированы только с информацией о switches.

Примеры

iex>  OptionParser.to_argv([foo_bar: "baz"])
["--foo-bar", "baz"]
iex>  OptionParser.to_argv([bool: true, bool: false, discarded: nil])
["--bool", "--no-bool"]

Некоторые переключатели выдают разные значения в зависимости от флага переключателя:

iex> OptionParser.to_argv([number: 2], switches: [])
["--number", "2"]
iex> OptionParser.to_argv([number: 2], switches: [number: :count])
["--number", "--number"]

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.4.5/OptionParser.html

Spec-Zone.ru

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