@@ -30,36 +30,33 @@ defmodule OptionParser do
3030 Elixir converts switches to underscored atoms, so `--source-path` becomes
3131 `:source_path`. This is done to better suit Elixir conventions. However, this
3232 means that switches can't contain underscores and switches that do contain
33- underscores are always returned in the list of invalid options .
33+ underscores are always returned in the list of invalid switches .
3434
35- Without any options, this function will try to parse all switches in the `argv`.
35+ When parsing, it is common to list switches and their expected types:
3636
37- iex> OptionParser.parse(["--debug"])
37+ iex> OptionParser.parse(["--debug"], switches: [debug: :boolean] )
3838 {[debug: true], [], []}
3939
40- iex> OptionParser.parse(["--source", "lib"])
40+ iex> OptionParser.parse(["--source", "lib"], switches: [source: :string] )
4141 {[source: "lib"], [], []}
4242
43- iex> OptionParser.parse(["--source-path", "lib", "test/enum_test.exs", "--verbose"])
43+ iex> OptionParser.parse(["--source-path", "lib", "test/enum_test.exs", "--verbose"],
44+ ...> switches: [source_path: :string, verbose: :boolean])
4445 {[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}
4546
46- Switches followed by a value will be assigned the value, as a string.
47- Switches without an argument, like `--debug` in the examples above, will
48- automatically be set to `true`.
47+ We will explore the valid switches and operation modes of option parser below.
4948
5049 ## Options
5150
5251 The following options are supported:
5352
5453 * `:switches` or `:strict` - see the "Switch definitions" section below
54+ * `:allow_nonexistent_atoms` - see the "Parsing dynamic switches" section below
5555 * `:aliases` - see the "Aliases" section below
56- * `:allow_nonexistent_atoms` - see the "Parsing undefined switches" section below
5756
5857 ## Switch definitions
5958
60- Often it is better to explicitly list the known
61- switches and their formats. The switches can be specified via one of two
62- options:
59+ Switches can be specified via one of two options:
6360
6461 * `:switches` - defines some switches and their types. This function
6562 still attempts to parse switches that are not in this list.
@@ -90,20 +87,20 @@ defmodule OptionParser do
9087 * `:float` - parses the value as a float
9188 * `:string` - parses the value as a string
9289
93- If a switch can't be parsed according to the given type, it is returned
94- in the invalid options list.
90+ If a switch can't be parsed according to the given type, it is
91+ returned in the invalid options list.
9592
9693 ### Modifiers
9794
9895 Switches can be specified with modifiers, which change how
9996 they behave. The following modifiers are supported:
10097
101- * `:keep` - keeps duplicated items instead of overriding them; works with
102- all types except `:count`. Specifying `switch_name: :keep` assumes the
103- type of `:switch_name` will be `:string`.
98+ * `:keep` - keeps duplicated items instead of overriding them;
99+ works with all types except `:count`. Specifying `switch_name: :keep`
100+ assumes the type of `:switch_name` will be `:string`.
104101
105- Note that if you want to use `:keep` with a type other than `:string`, use a list
106- as the type for the switch. For example: `[foo: [:integer, :keep]]`.
102+ To use `:keep` with a type other than `:string`, use a list as the type
103+ for the switch. For example: `[foo: [:integer, :keep]]`.
107104
108105 ### Negation switches
109106
@@ -113,14 +110,45 @@ defmodule OptionParser do
113110 iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean])
114111 {[op: false], ["path/to/file"], []}
115112
116- ### Parsing undefined switches
113+ ### Parsing dynamic switches
114+
115+ `OptionParser` also includes a dynamic mode where it will attempt to parse
116+ switches dynamically. Such can be done by not specifying the `:switches` or
117+ `:strict` option.
118+
119+ iex> OptionParser.parse(["--debug"])
120+ {[debug: true], [], []}
121+
117122
118- By default, only arguments that have defined atom representation will be parsed.
119- This happens because creating atoms at runtime is considered to be unsafe,
120- but you can still force creation of atoms by passing `allow_nonexistent_atoms: true`
121- to the list of function options.
123+ Switches followed by a value will be assigned the value, as a string. Switches
124+ without an argument, like `--debug` in the examples above, will automatically be
125+ set to `true`.
122126
123- This is useful when you are building command-line applications that receive dynamically-named arguments.
127+ Since Elixir converts switches to atoms, the dynamic mode will only parse
128+ switches that translates to atoms used by the runtime. Therefore, the code below
129+ likely won't parse the given option since the `:option_parser_example` atom is
130+ never used anywhere:
131+
132+ OptionParser.parse(["--option-parser-example"])
133+ # Does nothing more...
134+
135+ However, the code below does since the `:option_parser_example` atom is used
136+ at some point later (or earlier) on:
137+
138+ {opts, _, _} = OptionParser.parse(["--option-parser-example"])
139+ opts[:option_parser_example]
140+
141+ In other words, when using dynamic mode, Elixir will do the correct thing and
142+ only parse options that are used by the runtime, ignoring all others. If you
143+ would like to parse all switches, regardless if they exist or not, you can
144+ force creation of atoms by passing `allow_nonexistent_atoms: true` as option.
145+ Such option is useful when you are building command-line applications that
146+ receive dynamically-named arguments but must be used with care on long-running
147+ systems.
148+
149+ Switches followed by a value will be assigned the value, as a string.
150+ Switches without an argument, like `--debug` in the examples above, will
151+ automatically be set to `true`.
124152
125153 ## Aliases
126154
@@ -213,10 +241,12 @@ defmodule OptionParser do
213241
214242 ## Example
215243
216- iex> OptionParser.parse_head(["--source", "lib", "test/enum_test.exs", "--verbose"])
244+ iex> OptionParser.parse_head(["--source", "lib", "test/enum_test.exs", "--verbose"],
245+ ...> switches: [source: :string, verbose: :boolean])
217246 {[source: "lib"], ["test/enum_test.exs", "--verbose"], []}
218247
219- iex> OptionParser.parse_head(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"])
248+ iex> OptionParser.parse_head(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
249+ ...> switches: [source: :string, verbose: :boolean, unlock: :boolean])
220250 {[verbose: true, source: "lib"], ["test/enum_test.exs", "--unlock"], []}
221251
222252 """
@@ -236,10 +266,12 @@ defmodule OptionParser do
236266
237267 ## Examples
238268
239- iex> OptionParser.parse_head!(["--source", "lib", "path/to/file", "--verbose"])
269+ iex> OptionParser.parse_head!(["--source", "lib", "path/to/file", "--verbose"],
270+ ...> switches: [source: :string, verbose: :boolean])
240271 {[source: "lib"], ["path/to/file", "--verbose"]}
241272
242- iex> OptionParser.parse_head!(["--number", "lib", "test/enum_test.exs", "--verbose"], strict: [number: :integer])
273+ iex> OptionParser.parse_head!(["--number", "lib", "test/enum_test.exs", "--verbose"],
274+ ...> strict: [number: :integer])
243275 ** (OptionParser.ParseError) 1 error found!
244276 --number : Expected type integer, got "lib"
245277
@@ -309,7 +341,6 @@ defmodule OptionParser do
309341 * `{:error, rest}` - there are no switches at the head of the given `argv`
310342
311343 """
312-
313344 @ spec next ( argv , options ) ::
314345 { :ok , key :: atom , value :: term , argv } |
315346 { :invalid , String . t , String . t | nil , argv } |
0 commit comments