optparse-lite 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS.md ADDED
@@ -0,0 +1,4 @@
1
+ # optparse-lite news
2
+
3
+ ### 0.0.0 (2010-05-12)
4
+ * how awesome is it to have a fully functioning gem at 100% coverage before it is even published or documented? I'll tell you: quite awesome
data/README ADDED
@@ -0,0 +1,37 @@
1
+ <embed style='float: right'
2
+ src="svg/not-funny.svg" width="175px" height="130px"
3
+ type="image/svg+xml"
4
+ pluginspage="http://www.adobe.com/svg/viewer/install/"
5
+ />
6
+
7
+ # optparse-lite
8
+
9
+ #### _what the world needs now_ ####
10
+
11
+
12
+ ## Summary
13
+
14
+ You've seen Getopt::Long, OptionParser, Rake, Thor? What the world needs now is one more command-line parser. Arbitrarily deeply nested subcommands (lazily loaded), colors, manpage generation, usage syntax generation, option-parsing adapter interface.[^maybe]
15
+
16
+
17
+ ## Description
18
+
19
+ You've seen Getopt::Long, OptionParser, Thor? What the world needs now is one more command-line parser. This serves as a backend command line parser that passes the option-parsing portion of it off to OptionParser, Trollop, or any other option-parser that has an adapter[^adapter]. But the parts it *does* do are really exciting: It features arbitrarily deeply nested subcommands, optionally colorized help screens with smart formatting, automatically generated usage syntaxes, manpage generation[^maybe2], lazy-loading of subcommands, and (get this:) you can turn your command line app into a web app. (is processing a form then displaying a record really that different from CLI that does the same?)[^maybe3]
20
+
21
+ ## Awesome
22
+ * [<%= rcov_last_percentage_pretty %> test coverage](/coverage/) by the authority vested in [rcov](http://eigenclass.org/hiki.rb?rcov)
23
+ * <%= rcov_last_sloc_pretty %> source lines of code in a [single file](http://github.com/hipe/optparse-lite/blob/master/lib/optparse-lite.rb)
24
+ * zero dependencies on anything&reg; except ruby 1.8.7
25
+
26
+
27
+ These and more exciting features guarantee that what everyone's been saying will be true: that 2011 will indeed be the year for command-line interfaces.
28
+
29
+ Like what you hear and can't wait to get typing? [Install](/installation/) it then [use](/usage/) it!
30
+
31
+ <br />
32
+ <hr />
33
+ ### _Footnotes_
34
+ [^maybe]: some of these features are in the works, or were working at one point but are part of a grand refactor, *or* will be a part of `optparse-heavy` (vaporware from the future, not yet arrived)
35
+ [^maybe2]: from the future (_ibid._)
36
+ [^maybe3]: from the future (_ibid. ibid._)
37
+ [^adapter]: currently there is only an adapter for Trollop!
@@ -0,0 +1,57 @@
1
+ require 'rake/testtask.rb'
2
+ require File.expand_path('../lib/optparse-lite.rb', __FILE__)
3
+ require File.expand_path('../lib/optparse-lite/test/gentest/tasks', __FILE__)
4
+ require 'nandoc/extras/rcov-task'
5
+
6
+ task :default => :test
7
+
8
+ require 'jeweler'
9
+
10
+ require 'nandoc/parse-readme'
11
+
12
+ Jeweler::Tasks.new do |s|
13
+ s.authors = ['Chip Malice']
14
+ s.description = NanDoc::ParseReadme.description('README')
15
+ s.email = 'chip.malice@gmail.com'
16
+ s.executables = []
17
+ s.files = FileList['[A-Z]*', '{bin,doc,generators,lib,test}/**/*']
18
+ s.homepage = 'http://optparse-lite.hipeland.org'
19
+ s.name = 'optparse-lite'
20
+ s.rubyforge_project = 'optparse-lite'
21
+ s.summary = NanDoc::ParseReadme.summary('README')
22
+ end
23
+
24
+ Rake::TestTask.new do |t|
25
+ t.verbose = true
26
+ t.warning = true
27
+ end
28
+
29
+ me = "\e[35mopl\e[0m "
30
+
31
+ desc "#{me}put rcov coverage html docs into mysite/output"
32
+ NanDoc::RcovTask.new(:rcov) do |t|
33
+ t.test_files = FileList['test/test*.rb']
34
+ t.verbose = true
35
+ t.rcov_opts << "--text-report"
36
+ t.rcov_opts << "--exclude '.*gem.*'"
37
+ t.rcov_opts << "--exclude '.*treebis*'"
38
+ t.rcov_opts << "--include-file 'optparse-lite/lib'"
39
+ t.output_dir = 'mysite/output/coverage'
40
+ end
41
+
42
+
43
+ desc "#{me}hack turns the installed gem into a symlink to this directory"
44
+ task :hack do
45
+ kill_path = %x{gem which optparse-lite}
46
+ kill_path = File.dirname(File.dirname(kill_path))
47
+ new_name = File.dirname(kill_path)+'/ok-to-erase-'+File.basename(kill_path)
48
+ FileUtils.mv(kill_path, new_name, :verbose => 1)
49
+ this_path = File.dirname(__FILE__)
50
+ FileUtils.ln_s(this_path, kill_path, :verbose => 1)
51
+ end
52
+
53
+ Hipe::GenTest::GenTestTask.new
54
+
55
+ Hipe::GenTest::UnGenTask.new
56
+
57
+ # FileList['tasks/**/*.rake'].each { |task| import task }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,436 @@
1
+ ---
2
+ stylesheets: hopes-and-dreams
3
+
4
+ javascripts:
5
+ # - /vendor/jquery-current/dist/jquery.js
6
+ - /js/jquery-1.4.3.pre-hack-me.js
7
+ - /vendor/jquery-ui/ui/jquery.ui.core.js
8
+ - /vendor/jquery-ui/ui/jquery.ui.widget.js
9
+ - /vendor/jquery-ui/ui/jquery.ui.mouse.js
10
+ - /js/jquery.ui.draggable-hack-me.js
11
+ - /js/for-graphle-my-vizzle.js
12
+ - self
13
+
14
+ javascripts-off: [/vendor/jquery-1.3.js]
15
+ ---
16
+ # optparse-lite
17
+
18
+ ## high concept
19
+
20
+ [Trollop](http://trollop.rubyforge.org/) "doesn't require you to subclass some shit just to use a damn option parser." To use Optparse-lite, however, you will need to make at least one module or class and `include OptparseLite` unto it. Here's why:
21
+
22
+ OptparseLite (at least partially) parses a stream of input characters, turns them into a parse tree[^tree] of a request and dispatches it to the appropriate locus of logic which fulfills the user's wishes and presents a response in the form of the user's fulfilled dreams _(fig. 1)_.
23
+
24
+ <div class="crazy-pic" id="fig-1">
25
+ <div class="wrap-1">
26
+ <div class="wrap-2">
27
+ <div class="you box"><div class="label">you</div></div>
28
+ <div class="opl box"><div class="label">app</div></div>
29
+ </div>
30
+ <div class="backlay">
31
+ <svg preserveAspectRatio="xMidYMid slice" style="width:100%; height:100%; position:absolute; top:0; left:2px; z-index:-1;" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
32
+ <g id='thing-to-spin' transform='rotate(0, 0, 0)'>
33
+ <path d="M100,30 C 120,20 160,20 188,30 l0,-10 l10,18 l-16,14 l4,-12 C 160,30 120,30 103,40 L100,30 " fill="#cceeff" id="arrow1" stroke-width="2" stroke="#777777" />
34
+
35
+ <path d="M188,68 C 160,78 140,78 110,68 L 110,80 102,60 115,44 111,58 C 140,67 170,67 185,58 z" fill="#cceeff" id="arrow2" stroke-width="2" stroke="#777777" />
36
+
37
+ <path d="M110,65 C 140,75 160,75 188,65" fill="none" id="words2" stroke="none" />
38
+
39
+ <text fill="black" font-size="10.5">
40
+ <textPath xlink:href="#words2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;dreams</textPath>
41
+ </text>
42
+
43
+ <path d="M100,37 C 120,29 138,24 180,37" fill="none" id="words1" stroke="none" />
44
+ <text fill="black" font-size="10.5">
45
+ <textPath xlink:href="#words1">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;wishes</textPath>
46
+ </text>
47
+ </g>
48
+ </svg>
49
+ </div>
50
+ <div class='click-overlay'>
51
+ <div class='left-half'>
52
+ </div>
53
+ <div class='right-half'>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ <div class="caption">
58
+ fig. 1 - apps turn your wishes into dreams
59
+ </div>
60
+ </div>
61
+
62
+ Conceptually these loci are usually referred to as `command`s. In practice it makes good sense for them to be implemented by ruby methods, which form a clean analog / isomorphism with [cli](/high-concept/terms#cli) commands for several reasons expounded on below with vivid math.[^nomod]
63
+
64
+ None of this is especially unique to OptparseLite, but it is important that we frame the discussion in these terms to understand this important emerging field of command line processing.
65
+
66
+ However note that most option parsing libraries don't need to address all below issues because they don't deal with _what_ the commands are, they just deal with parsing the options _of_ the command(s).[^nocom]
67
+
68
+ It is thus a philosophical burden of proof that OptparseLite alone bears on its narrow but ample shoulders; because unlike its peers it cannot remain blissfully ignorant of the exquisite symphony of the stars that governs the motion of planets of data guided as they are by their gravitational forces of logic along their predetermined (and sometimes determinate) paths in the infinite tango that plays out below our fingertips daily.
69
+
70
+ ### modules can model user interfaces
71
+
72
+ OptparseLite effectively lets you model the user interface of your application in terms of a [set](/high-concept/terms#set) of commands, each of which takes a [set](/high-concept/terms#set) of zero or more options and a [list](/high-concept/terms#list) of zero or more arguments. OptparsLite is a grammar for defining interfaces composed of commands, and a tool for parsing requests per the interface defined by the grammar you create in this grammar.
73
+
74
+ The grammar you define with OptparseLite defines the [set](/high-concept/terms#set) (or a superset) of all valid requests for your application. You do this by defining the set of all valid commands. You define a command by defining the set of all valid requests for each command. You do this by defining the set of all valid options and arguments each command takes. You do this by defining a set of valid values that each option/argument takes.
75
+
76
+
77
+ <div id="fig-2">
78
+ <h3>the grand isomorphicism</h3>
79
+ <h4><em>a grand meta-narrative</em></h4>
80
+ <div class="snack-wrap">
81
+ <div class="backlay">
82
+ <svg preserveAspectRatio="xMidYMid slice" style="width:100%; height:100%; position:absolute; top:0; left:0px; z-index:-1;" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
83
+ <path class="name-arcmodmeth lig-pos-mod--pos-circmeth slide-1" d="M 72,35 72,59" fill="#777777" stroke-width="2" stroke="#777777" />
84
+ <circle class="name-circmeth lig-pos-meth--tail-arcmodmeth slide-1" cx="72" cy="63.5" fill="none" r="3.5" stroke-width="1.66" stroke="#555555" />
85
+
86
+ <path class="name-arcmethparam lig-pos-meth--pos-circparam slide-6" d="M 72,100 72,127" fill="#777777" stroke-width="2" stroke="#777777" />
87
+ <circle class="name-circparam lig-pos-param--tail-arcmethparam slide-6" cx="72" cy="130.5" fill="none" r="3.5" stroke-width="1.66" stroke="#555555" />
88
+
89
+ <path class="name-ridgidoptsparam lig-pos-param--tail-arcoptsparam slide-11" d="M 105,159 l 15,-5 0,10 z" fill="none" stroke-width="2" stroke="#777777" />
90
+ <path class="name-arcoptsparam lig-pos-ridgidoptsparam--pos-opts slide-11" d="M 119,159 130,159 130,220" fill="none" stroke-width="2" stroke="#777777" />
91
+
92
+ <path class="name-arctrailparam lig-pos-ridgidtrailparam--pos-trail slide-16" d="M 15,201 15,285" fill="#777777" stroke-width="2" stroke="#777777" />
93
+ <path class="name-ridgidtrailparam lig-pos-param--pos-arctrailparam slide-16" d="M 10,201 l 5,-13 5,13 z" fill="none" stroke-width="2" stroke="#777777" />
94
+
95
+ <path class="name-rsplat lig-pos-trail--tail-asplat slide-21" d="M 10,365 l 5,-13 5,13 z" fill="none" stroke-width="2" stroke="#777777" />
96
+ <path class="name-asplat lig-pos-rsplat--pos-splat slide-21" d="M 15,364 15,390" fill="#777777" id="tallz" stroke-width="2" stroke="#777777" />
97
+
98
+ <path class="name-arcintrcmd lig-pos-intr--pos-circcmd slide-51" d="M 358,35 358,59" fill="#777777" stroke-width="2" stroke="#777777" />
99
+ <circle class="name-circcmd lig-pos-cmd--pos-arcintrcmd slide-51" cx="358" cy="63.5" fill="none" r="3.5" stroke-width="1.66" stroke="#555555" />
100
+
101
+ <path class="name-arccmdarg lig-pos-cmd--pos-circarg slide-56" d="M 358,100 358,127" fill="#777777" stroke-width="2" stroke="#777777" />
102
+ <circle class="name-circarg lig-pos-arccmdarg--pos-arg slide-56" cx="358" cy="130.5" fill="none" r="3.5" stroke-width="1.66" stroke="#555555" />
103
+
104
+ <path class="name-arccmdopts2 lig-pos-cmd--pos-opts2 slide-61" d="M 407,100 407,220" fill="#777777" stroke-width="2" stroke="#777777" />
105
+
106
+ <path class="name-arctrail2arg lig-pos-ridgidtrail2arg--pos-trail2 slide-66" d="M 298,201 298,285" fill="#777777" stroke-width="2" stroke="#777777" />
107
+ <path class="name-ridgidtrail2arg lig-pos-arg slide-66" d="M 292,201 l 6,-13 5,13 z" fill="none" stroke-width="2" stroke="#777777" />
108
+
109
+ <path class="name-arcopts2opt lig-pos-opts2--pos-circopt slide-76" d="M 415,255 415,278" fill="#777777" id="opt" stroke-width="2" stroke="#777777" />
110
+ <circle class="name-circopt lig-pos-opt slide-76" cx="415" cy="281" fill="none" r="3.5" stroke-width="1.66" stroke="#555555" />
111
+
112
+ <path class="name-ridgidsplat2 lig-pos-trail2--pos-arcsplat2 slide-71" d="M 292,365 l 6,-13 5,13 z" fill="none" id="bliz9" stroke-width="2" stroke="#777777" />
113
+ <path class="name-arcsplat2 lig-pos-ridgidsplat2--pos-splat2 slide-71" d="M 298,364 298,390" fill="#777777" stroke-width="2" stroke="#777777" />
114
+
115
+ <path class="name-arcswitch lig-pos-switch slide-81" d="M 417,397 427,397 427,367 410,367 410,340" fill="none" stroke-width="2" stroke="#777777" />
116
+
117
+ <path class="name-arcpr lig-pos-pr slide-86" d="M 417,464 427,464 427,397" fill="none" stroke-width="2" stroke="#777777" />
118
+
119
+ <path class="name-atall lig-pos-po--pos-ridgidopt slide-91" d="M 417,517 427,517 427,367 410,367 410,340" fill="none" stroke-width="2" stroke="#777777" />
120
+ <path class="name-ridgidopt lig-pos-opt--tail-atall slide-81" d="M 411,339 l -6,0 5,-15 5,15 z" fill="none" stroke-width="2" stroke="#777777" />
121
+
122
+ </svg>
123
+
124
+ </div>
125
+ <div class="left-col">
126
+
127
+ <div class="mod ruby-construct square short slide-1">ruby module</div>
128
+ <div class="meth ruby-construct square short slide-1">public method</div>
129
+ <div class="param ruby-construct square dubs slide-6" style="width: 81px">method parameter</div>
130
+ <div class="opts ruby-construct square short slide-11">option hash</div>
131
+ <div class="trail ruby-construct square slide-16">trailing optional parameter</div>
132
+ <div class="splat ruby-construct square slide-21">splat</div>
133
+
134
+ <div class="expl arc-1 mod-meth has-many slide-1">has many</div>
135
+ <div class="expl arc-2 mod-meth has-many slide-6">has many</div>
136
+ <div class="expl arc-3 mod-meth is-a slide-11">is a</div>
137
+ <div class="expl arc-4 mod-meth is-a slide-16">is a</div>
138
+ <div class="expl arc-5 mod-meth is-a slide-21">is a</div>
139
+
140
+ </div>
141
+ <div class="mid-col">
142
+
143
+ <div class="iso iso-1 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
144
+ <div class="iso iso-2 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
145
+ <div class="iso iso-3 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
146
+ <div class="iso iso-4 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
147
+ <div class="iso iso-5 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
148
+ <div class="iso iso-6 slide-201"><div class="l"><object class="arrow-left" data="/svg/arrow-left.svg" type="image/svg+xml" /></div><div class="m">isomorphs</div><div class="r"><object class="arrow-right" data="/svg/arrow-right.svg" type="image/svg+xml" /></div></div>
149
+
150
+ </div>
151
+ <div class="right-col">
152
+ <div class="intr app square short slide-51">app interface</div>
153
+ <div class="cmd app square short slide-51">command</div>
154
+ <div class="arg app square dubs slide-56" style="width: 81px">positional argument</div>
155
+ <div class="opts2 app square slide-61">options</div>
156
+
157
+ <div class="opt app square slide-76">opt</div>
158
+
159
+ <div class="switch app square slide-81">switch</div>
160
+ <div class="pr app square slide-86">param. required</div>
161
+ <div class="po app square slide-91">param. optional</div>
162
+
163
+ <div class="trail2 app square slide-66">trailing optional argument</div>
164
+ <div class="splat2 app square slide-71">splat arg</div>
165
+
166
+ <div class="expl arc-21 mod-meth has-many slide-51">has many</div>
167
+ <div class="expl arc-22 mod-meth has-many slide-56">has many</div>
168
+ <div class="expl arc-23 mod-meth is-a slide-66">is a</div>
169
+ <div class="expl arc-24 mod-meth has-one slide-61">has one</div>
170
+ <div class="expl arc-26 mod-meth is-a slide-71">is a kind of</div>
171
+
172
+ </div>
173
+ <div class="balloon balloon-1 slide-1-only">
174
+ <p>
175
+ A ruby module has zero or more methods. (Classes are modules too!)
176
+ </p>
177
+ <pre class='ruby example-smaller'><span class="keyword">module </span><span class="module">SomeModule</span>
178
+ <span class="keyword">def </span><span class="method">foo</span>
179
+ <span class="keyword">end</span>
180
+ <span class="keyword">def </span><span class="method">bar</span>
181
+ <span class="keyword">end</span>
182
+ <span class="keyword">end</span>
183
+ </pre>
184
+ <button class="next">&#187;</button>
185
+ </div>
186
+
187
+
188
+
189
+ <div class="balloon balloon-2 slide-6-only">
190
+ <p>A ruby method <em>has many</em> parameters --
191
+ A ruby method signature defines the names (and maybe default values)
192
+ for the zero or more formal parameters it takes.
193
+ (A ruby method call has zero or more arguments.)
194
+ </p>
195
+ <pre class='ruby example-smaller'><span class="keyword">def </span><span class="method">foo</span> <span class="ident">arg1</span><span class="punct">,</span> <span class="ident">arg2</span><span class="punct">='</span><span class="string">blah</span><span class="punct">'</span>
196
+ <span class="comment"># do some foo...</span>
197
+ <span class="keyword">end</span>
198
+ </pre>
199
+ <button class="next">&#187;</button>
200
+ </div>
201
+
202
+
203
+
204
+
205
+ <div class="balloon balloon-3 slide-11-only" style='width: 268px'>
206
+ <p>An "options hash" is a <em>kind of</em> method parameter.</p>
207
+ <pre class='ruby' style='width: 257px'><span class="keyword">def </span><span class="method">foo</span> <span class="ident">arg1</span><span class="punct">,</span> <span class="ident">opts</span><span class="punct">={}</span>
208
+ <span class="ident">opts</span> <span class="punct">=</span> <span class="punct">{</span><span class="symbol">:some=</span><span class="punct">&gt;'</span><span class="string">default</span><span class="punct">'}.</span><span class="ident">merge</span><span class="punct">(</span><span class="ident">opts</span><span class="punct">)</span>
209
+ <span class="comment"># ...</span>
210
+ <span class="keyword">end</span>
211
+ </pre>
212
+ <p>
213
+ Ruby has 'syntactic sugar' that allows name-value paired option
214
+ hashes appearing at the end of a method call not need the curly braces.
215
+ </p>
216
+ <pre class='ruby' style='border:4px solid #DDDDDD; width:308px;'><span class="ident">foo</span> <span class="punct">&quot;</span><span class="string">bar</span><span class="punct">&quot;,</span> <span class="symbol">:bob</span> <span class="punct">=&gt;</span> <span class="punct">&quot;</span><span class="string">loblaw's</span><span class="punct">&quot;,</span> <span class="symbol">:law</span> <span class="punct">=&gt;</span> <span class="punct">'</span><span class="string">blog</span><span class="punct">'</span><span class="string"><span class="normal">
217
+ </span></span></pre>
218
+
219
+ <p>
220
+ So typically when a method takes an "options hash" it appears as the last parameter.
221
+ </p>
222
+ <p style='font-size: 0.8em'><em>For reasons that might become clear,
223
+ optparse-lite does not utilize this idiom as an isomorphicism.
224
+ </em></p>
225
+
226
+ <div class='spacer-gif'>&#160;</div>
227
+ <button class="next lower">&#187;</button>
228
+ </div>
229
+ <div class="balloon balloon-4 slide-16-only" style='width: 267px'>
230
+ <p>Actual parameters passed to a method call are <em>positionally semantic</em>, by which i mean that the interpreter
231
+ figures out which actual parameters correspond to which formal parameters by their order (i.e. index)
232
+ (a ridiculously obvious point which sounds confusing when you explain it).
233
+ </p>
234
+ <p>Although it wouldn't necessarily have to be this way, ruby follows the syntax rule for all other
235
+ such programming languages and allows you to specify default arguments for parameters IFF they are
236
+ contiguous and at the end of the list of parameters.</p>
237
+ <pre class='ruby'><span class="keyword">def </span><span class="method">baby</span> <span class="ident">jug</span><span class="punct">,</span> <span class="ident">funny</span><span class="punct">='</span><span class="string">default</span><span class="punct">';</span> <span class="keyword">end</span>
238
+ </pre>
239
+ <pre class='ruby'><span class="ident">baby</span><span class="punct">('</span><span class="string">funny</span><span class="punct">')</span> <span class="comment"># not funny</span>
240
+ </pre>
241
+ <p>(Imagine a method that takes five arguments where the first, third and last have defaults and are
242
+ thereby optional. No reason. just for fun. Some SQL syntax is sorta like this.)</p>
243
+ <p>The only point in all this is that contiguous trailing parameters of a method
244
+ who take defaults are effectively optional. </p>
245
+ <div class='spacer-gif'></div>
246
+ <button class="next">&#187;</button>
247
+ </div>
248
+
249
+
250
+
251
+ <div class="balloon balloon-5 slide-21-only">
252
+ <p>One <em>kind of</em> trailing option parameter is a splat.</p>
253
+ <p>(in ruby 1.8.7 the splat must be the last parameter.)</p>
254
+ <p>A splat means that the method can take an infinite number of arguments
255
+ (or some big number of them), and that those arguments that don't have a
256
+ positional named parameter at the beginning get turned into elements of an
257
+ array that is passed as the effective last parameter of the method call.
258
+ </p>
259
+ <pre class='ruby'><span class="keyword">def </span><span class="method">splat</span><span class="punct">(*</span><span class="ident">blah</span><span class="punct">)</span>
260
+ <span class="ident">puts</span> <span class="ident">blah</span><span class="punct">.</span><span class="ident">map</span><span class="punct">(&amp;</span><span class="symbol">:upcase</span><span class="punct">).</span><span class="ident">join</span><span class="punct">('</span><span class="string"> </span><span class="punct">')</span>
261
+ <span class="keyword">end</span>
262
+ <span class="ident">splat</span> <span class="punct">'</span><span class="string">baby</span><span class="punct">',</span> <span class="punct">'</span><span class="string">jug</span><span class="punct">',</span> <span class="punct">'</span><span class="string">not</span><span class="punct">',</span> <span class="punct">'</span><span class="string">funny</span><span class="punct">'</span>
263
+ <span class="comment"># BABY JUG NOT FUNNY</span>
264
+ </pre>
265
+ <div class='spacer-gif'>&#160;</div>
266
+ <button class="next">&#187;</button>
267
+ </div>
268
+ <div class="balloon balloon-6 slide-51-only">
269
+ <p>An application interface is made up of <em>many</em> commands.</p>
270
+ <p><em>(note API's's are, too)</em></p>
271
+ <div style='height: 2px'>&#160;</div>
272
+ <button class="next">&#187;</button>
273
+ </div>
274
+ <div class="balloon balloon-7 slide-56-only">
275
+ <p>A CLI command <em>has many</em> (positional) arguments.</p>
276
+ <p>It could have zero. Note this isomorphs with parameters of a method.</p>
277
+ <pre class='terminal' style='border:8px solid #DDDDDD; width: 302px'><span class='prompt'>~ &#62;</span> git checkout -h
278
+ usage: git checkout [options] &#60;branch&#62;
279
+ </pre>
280
+ <p>The above git command has one required positional argument.</p>
281
+ <div class='spacer-gif'></div>
282
+ <button class="next">&#187;</button>
283
+ </div>
284
+ <div class="balloon balloon-8 slide-61-only">
285
+ <p>An optparse-lite command (method) gets passed one (or zero) options structure (hash).</p>
286
+ <pre class='ruby'><span class="ident">opts</span> <span class="punct">{</span>
287
+ <span class="ident">opt</span> <span class="punct">'</span><span class="string">--[no-]mames</span><span class="punct">',</span> <span class="symbol">:juae</span>
288
+ <span class="punct">}</span>
289
+ <span class="keyword">def </span><span class="method">do_it</span> <span class="ident">opts</span><span class="punct">,</span> <span class="ident">a</span><span class="punct">,</span> <span class="ident">b</span><span class="punct">=</span><span class="constant">nil</span>
290
+ <span class="comment"># do it</span>
291
+ <span class="keyword">end</span>
292
+ </pre>
293
+ <p><b>opts</b> is passed as the first parameter above.</p>
294
+ <div style='top: 2px'></div>
295
+ <button class="next">&#187;</button>
296
+ </div>
297
+
298
+
299
+
300
+ <div class="balloon balloon-9 slide-66-only">
301
+ <p>One kind of positional argument <em>is a</em> trailing optional argument.</p>
302
+ <pre class='ruby'><span class="keyword">def </span><span class="method">do_it</span> <span class="ident">opts</span><span class="punct">,</span> <span class="ident">foo</span><span class="punct">,</span> <span class="ident">bar</span><span class="punct">=</span><span class="constant">nil</span>
303
+ <span class="comment"># do it</span>
304
+ <span class="keyword">end</span>
305
+ </pre>
306
+ <p><b>bar</b> is a trailing optional argument above.
307
+ </p>
308
+ <div style='top: 2px'></div>
309
+ <button class="next">&#187;</button>
310
+ </div>
311
+ <div class="balloon balloon-10 slide-71-only">
312
+ <p>One kind of trailing optional argument <em>is a</em> splat argument.</p>
313
+ <p><em>Note that if you have any splat argument, you can only have one.</em></p>
314
+ <div style='text-align: right; float: right' class='slide-71-only'>
315
+ <button class="next" style='position: relative; bottom: 0px; right: 0px'>&#187;</button>
316
+ </div>
317
+ <p>In the below git command, <b>filepattern</b> is a splat argument.</p>
318
+ <pre class='terminal' style='width: 369px; border: 8px solid #DDDDDD;'>~ &#62; git add -h
319
+ usage: git add [options] [--] &#60;filepattern&#62;...
320
+ </pre>
321
+ </div>
322
+ <div class="balloon balloon-11 slide-76-only">
323
+ <p>An options structure (hash) is made up of <em>many</em> options.</p>
324
+ <p><em>(as a hash is made up of many elements)</em></p>
325
+ <div class='spacer-gif'></div>
326
+ <button class="next">&#187;</button>
327
+ </div>
328
+ <div class="balloon balloon-12 slide-81-only">
329
+ <p>One kind of option <em>is a</em> switch (or <em>'flag'</em>)</p>
330
+ <p>This kind of option does not (and cannot) take an argument.</p>
331
+ <pre class='terminal' style='width: 369px; border:8px solid #DDDDDD; font-size: 9px'>~ &#62; git add -h
332
+ usage: git add [options] [--] &#60;filepattern&#62;...
333
+ ...
334
+ -f, --force allow adding otherwise ignored files
335
+ ...
336
+ </pre>
337
+ <p><b>--force</b> is a flag for the git <b>add</b> command. It does not take any arguments.</p>
338
+ <div class='spacer-gif'></div>
339
+ <button class="next">&#187;</button>
340
+ </div>
341
+ <div class="balloon balloon-13 slide-86-only">
342
+ <p>Another <em>kind of</em> option is the kind that takes a required parameter.</p>
343
+ <p>The git <b>checkout</b> command takes a <b>--branch</b> option which takes a required parameter.</p>
344
+ <button class="next" style=''>&#187;</button>
345
+ <pre class='terminal' style='font-size: 9px'>~ &#62; git co -h
346
+ usage: git checkout [options] &#60;branch&#62;
347
+ ...
348
+ -b &#60;new branch&#62; branch
349
+ ...
350
+ </pre>
351
+ </div>
352
+ <div class="balloon balloon-14 slide-91-only">
353
+ <p>Another <em>kind of</em> option is the kind that takes a parameter optionally.</p>
354
+ <p>The <b>git init</b> command has an option <b>--shared</b> which takes a parameter optionally.</p>
355
+ <p><b>--template</b> takes a parameter also but note that it is not optional.</p>
356
+ <pre class='terminal' style='border:9px solid #DDDDDD;font-size:9px;left:-165px;position:relative;width:387px;'>~ &#62; git init -h
357
+ usage: git init [-q | --quiet] [--bare] [--template=&#60;template-directory&#62;]
358
+ [--shared[=&#60;permissions&#62;]] [directory]
359
+ </pre>
360
+ <p><em>(These are not the same as options that have default parameters -- an option
361
+ that has a default value is not necessarily valid appearing on its own
362
+ without a parameter.)</em></p>
363
+ <div class='spacer-gif'></div>
364
+ <button class="next">&#187;</button>
365
+ </div>
366
+
367
+
368
+ <div class="clear"></div>
369
+ </div>
370
+ <div class="slide-control slide-control-top-left">
371
+ <div class="back-bar back-bar-lvl-1">&#160;</div>
372
+ <div class="back-bar back-bar-lvl-2">&#160;</div>
373
+ <div class="step step-1">1</div>
374
+ <div class="step step-2">2</div>
375
+ <div class="step step-3">3</div>
376
+ <div class="step step-4">4</div>
377
+ <div class="step step-5">5</div>
378
+ <div class="step step-6">6</div>
379
+ <div class="step step-7">7</div>
380
+ <br/>
381
+ <div class="step step-8">8</div>
382
+ <div class="step step-9">9</div>
383
+ <div class="step step-10">10</div>
384
+ <div class="step step-11">11</div>
385
+ <div class="step step-12">12</div>
386
+ <div class="step step-13">13</div>
387
+ <div class="step step-14">14</div>
388
+ <div class="step step-15">15</div>
389
+ </div>
390
+ <div class="slide-control slide-control-bottom-left">
391
+ <div class='fix'>
392
+ <div class="back-bar back-bar-wide">&#160;</div>
393
+ <div class="step step-1">1</div>
394
+ <div class="step step-2">2</div>
395
+ <div class="step step-3">3</div>
396
+ <div class="step step-4">4</div>
397
+ <div class="step step-5">5</div>
398
+ <div class="step step-6">6</div>
399
+ <div class="step step-7">7</div>
400
+ <div class="step step-8">8</div>
401
+ <div class="step step-9">9</div>
402
+ <div class="step step-10">10</div>
403
+ <div class="step step-11">11</div>
404
+ <div class="step step-12">12</div>
405
+ <div class="step step-13">13</div>
406
+ <div class="step step-14">14</div>
407
+ <div class="step step-15">15</div>
408
+ </div>
409
+ </div>
410
+
411
+ <div class="big-button-overlay">
412
+ <div class="opaque-backlay">&#160;</div>
413
+ <div class="frame">
414
+ <div class="banner top-banner">PUT ON YOUR LEARNING HAT</div>
415
+ <div class="button-play">
416
+ <svg preserveAspectRatio="xMidYMid slice" style="width:100%; height:100%; position:absolute; top:0; left:0px; z-index:0;" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
417
+ <path class="arrow-border" d="M 2,40 C 2,2 2,2 40,2 L 133,2 C 170,2 170,2 170,40 L 170,120 C 170,159 170,159 143,159 L 20,159 C 2,159 2,159 2,120 z" fill="#aaaaaa" stroke-width="2" stroke="#777777" />
418
+ <path class="arrow" d="M 27,18 l 115,65 -115,65 z" fill="#ffffff" stroke-width="2" stroke="#777777" />
419
+ </svg>
420
+ </div>
421
+ <div class="banner bottom-banner">AND LET THE AWESOME BEGIN</div>
422
+ </div>
423
+ </div>
424
+ </div>
425
+
426
+
427
+ You don't have to think of it this way if you're not into that kind of thing. This is no different from any other option parser; I just wanted to frame the discussion a bit.
428
+
429
+ Check out the awesome [usage](/usage/)
430
+
431
+ <br />
432
+ <hr />
433
+ ### _feetnote_ ###
434
+ [^tree]: the arguments node of your tree may have order that is semantic.
435
+ [^nocom]: `Trollop`, `OptionParser` and `Getopt::Long` are examples of option-parsing solutions that don't address the issue of parsing out the command.
436
+ [^nomod]: Using defined methods belonging to a special module isn't the only way to model commands. [Cri](http://rubygems.org/gems/cri) uses a class to model each command. [rip](http://hellorip.com/) at one point, like [rvm](http://rvm.beginrescueend.com/) uses a separate executable file for each command, in the conventional unix tradition. (But in fact an earlier version of rip was the inspiration for this whole project.)