# OptionParser: unexpected behaviour with -help

**URL:** <https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679>\
**Category:** Ruby\
**Created:** [May 24, 2009, 6:58am UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679 "2009-05-24T06:58:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 24, 2009, 6:58am UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/1 "2009-05-24T06:58:24Z")

</div>

I ran into some unexpected behaviour with the Ruby OptionParser class.  
When running this script (without any command line arguments) the output  
is as in the last, commented, line.

* * *

require ‘optparse’  
options = {}  
OptionParser.new do |opt|  
opt.on “–ex EXECUTABLE”, String do |val|  
options[:ex] = val  
end  
opt.on “–headers” do |val|  
options[:headers] = val  
end  
opt.parse(%w( -help ))  
end

puts options.inspect

# Output is {:ex=\>“lp”, :headers=\>true}

* * *

I don’t think that ‘-help’ should be treated the same as ‘-h -ex lp’ or  
‘-h --ex lp’. In particular, ‘-help’ may be a misspelling of the  
common ‘–help’ option. Am I doing something wrong? Is there a way to  
avoid this?

Thanks a lot,

Stephan

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 24, 2009, 11:21am UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/2 "2009-05-24T11:21:16Z")

</div>

Look at the source - /usr/lib/ruby/1.8/optparse.rb or somewhere similar  
on your system.

```
            # if no short options match, try completion with long
            # options.
            sw, = complete(:long, opt)

```

So it looks that if you stub out ‘complete’ you can get the behaviour  
you require: that is, I think you want -h to be treated as an error  
instead of as a shortcut for --headers, and ditto -e as an error instead  
of a shortcut for --ex

Alternatively, if only ‘-help’ is a problem, you could just handle this  
special case:

ARGV.each { |a| a.replace(’–help’) if a == ‘-help’ }

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 24, 2009, 5:50pm UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/3 "2009-05-24T17:50:51Z")

</div>

On 24.05.2009 06:58, Stephan W. wrote:

> ```
> options[:ex] = val
> 
> ```
> 
> end  
> opt.on “–headers” do |val|  
> options[:headers] = val  
> end  
> opt.parse(%w( -help ))

In addition to what Brian wrote, the line above is wrongly placed IMHO.  
You cannot know whether initialization of the OptionParser instance is  
completed when still inside the block. You should rather invoke #parse  
on the result of OptionParser.new.

> end
> 
> puts options.inspect

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 25, 2009, 8:42am UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/4 "2009-05-25T08:42:01Z")

</div>

Brian C. wrote:

> Look at the source - /usr/lib/ruby/1.8/optparse.rb or somewhere similar  
> on your system.
> 
> ```
> # if no short options match, try completion with long
> # options.
> sw, = complete(:long, opt)
> 
> ```
> 
> So it looks that if you stub out ‘complete’ you can get the behaviour  
> you require: that is, I think you want -h to be treated as an error  
> instead of as a shortcut for --headers, and ditto -e as an error instead  
> of a shortcut for --ex
> 
> Alternatively, if only ‘-help’ is a problem, you could just handle this  
> special case:
> 
> ARGV.each { |a| a.replace(’–help’) if a == ‘-help’ }

Well, thanks a lot for that. I feel the guessing game should be avoided  
– there’s too much potential for confusion.

Stephan

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 25, 2009, 8:42am UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/5 "2009-05-25T08:42:56Z")

</div>

Robert K. wrote:

> On 24.05.2009 06:58, Stephan W. wrote:
> 
> > ```
> > options[:ex] = val
> > 
> > ```
> > 
> > end  
> > opt.on “–headers” do |val|  
> > options[:headers] = val  
> > end  
> > opt.parse(%w( -help ))
> 
> In addition to what Brian wrote, the line above is wrongly placed IMHO.  
> You cannot know whether initialization of the OptionParser instance is  
> completed when still inside the block. You should rather invoke #parse  
> on the result of OptionParser.new.
> 
> > end
> > 
> > puts options.inspect

Good point – but the result is the same.

Stephan

> Kind regards
> 
> robert

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 26, 2009, 10:52pm UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/6 "2009-05-26T22:52:32Z")

</div>

On May 23, 2009, at 21:58, Stephan W. wrote:

> I don’t think that ‘-help’ should be treated the same as ‘-h -ex lp’  
> or  
> ‘-h --ex lp’. In particular, ‘-help’ may be a misspelling of the  
> common ‘–help’ option. Am I doing something wrong? Is there a way to  
> avoid this?

When you use - instead of – you invoke short-option-parsing like:

$ ruby -dvrubygems -e ‘raise rescue nil’  
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]  
Exception `LoadError' at /Library/Ruby/Site/1.8/rubygems.rb:1106 - no such file to load -- rubygems/defaults/operating_system Exception`LoadError’ at /Library/Ruby/Site/1.8/rubygems/  
config\_file.rb:35 - no such file to load – Win32API  
Exception `RuntimeError’ at -e:1 -  
$

Which is equivalent to:

ruby -d -v -r ubygems -e ‘raise rescue nil’

---

<div class="post-metadata">

**Author:** ![stephanwehner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/0ea827/32.png) [@stephanwehner](https://www.ruby-forum.com/u/stephanwehner)\
**Post date:** [May 28, 2009, 6:38pm UTC](https://www.ruby-forum.com/t/optionparser-unexpected-behaviour-with-help/168679/7 "2009-05-28T18:38:27Z")

</div>

Eric H. wrote:

> On May 23, 2009, at 21:58, Stephan W. wrote:
> 
> > I don’t think that ‘-help’ should be treated the same as ‘-h -ex lp’  
> > or  
> > ‘-h --ex lp’. In particular, ‘-help’ may be a misspelling of the  
> > common ‘–help’ option. Am I doing something wrong? Is there a way to  
> > avoid this?
> 
> When you use - instead of – you invoke short-option-parsing like:
> 
> $ ruby -dvrubygems -e ‘raise rescue nil’  
> ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]  
> Exception `LoadError' at /Library/Ruby/Site/1.8/rubygems.rb:1106 - no such file to load -- rubygems/defaults/operating_system Exception `LoadError’ at /Library/Ruby/Site/1.8/rubygems/  
> config\_file.rb:35 - no such file to load – Win32API  
> Exception `RuntimeError’ at -e:1 -  
> $
> 
> Which is equivalent to:
> 
> ruby -d -v -r ubygems -e ‘raise rescue nil’

There is some precedence for disabling this kind of command line  
parsing, see

[CmdLineParser.NotFlagException (JArgs command line option parsing library)](http://jargs.sourceforge.net/doc/api/jargs/gnu/CmdLineParser.NotFlagException.html)

[http://tinyurl.com/notflagexception](http://tinyurl.com/notflagexception)

Quote:

public static class CmdLineParser.NotFlagException  
extends CmdLineParser.UnknownOptionException

Thrown when the parsed commandline contains multiple concatenated  
short options, such as -abcd, where one or more requires a value.  
getMessage() returns an english human-readable error string.

End quote

This looks like a useful option to support.

Stephan
