I'm running into an issue with OptionParser's make_switch
.
My code parses three arguments and runs a test to see if my MANDATORY argument is here:
#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
options = OpenStruct.new
@argv = ARGV
optparse = OptionParser.new do |opts|
@opts=opts
usage = "USAGE: ./#{File.basename($0)} [-v] -p xxxxxx"
@opts.banner = usage
@opts.on( '-p', '--pdu [PDU]', 'Specify a PDU to configure') do |res|
options.pdu = true
$pdu_name = res
end
@opts.on( '-v', '--[no-]verbose', 'Run verbosely') do
options.verbose = true
end
@opts.on( '-?', '-help','Show this message') do
puts "Help Me!"
puts @opts
exit 1
end
end
begin
if not @argv.empty?
optparse.order!(@argv)
if !options.pdu
$stderr.puts "Options -p missing."
$stderr.puts "#{@opts}\n\n"
exit 1
end
else
$stderr.puts "ERROR: Arguments Required."
$stderr.puts "#{@opts}\n\n"
exit 1
end
rescue OptionParser::InvalidOption
$stderr.puts "ERROR: Invalid option."
$stderr.puts "#{@opts}\n\n"
exit 1
end
Everything works except -?
:
xxx$ ./myscript.rb -?
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:451:in
`parse': missing argument: -? (OptionParser::MissingArgument)
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1295:in `parse_in_order'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1254:in `catch'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1254:in `parse_in_order'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse.rb:1248:in `order!'
blabla
However -help
works perfectly:
xxxx$ ./myscript.rb -help
Help me!
USAGE: ./myscript.rb [-v] -p xxxxxx
-p, --pdu [PDU] Specify a PDU to configure
-v, --[no-]verbose Run verbosely
-?, -help Show this message
More surprisingly, -? -v
works too:
xxxx$ ./myscript.rb -? -v
Help Me!
USAGE: ./myscript.rb [-v] -p xxxxxx
-p, --pdu [PDU] Specify a PDU to configure
-v, --[no-]verbose Run verbosely
-?, -help Show this message
What did I do wrong?
The same issue occurs if I replace -?
with -h
in the code.
Perhaps a quick look at the (somewhat confusing) documentation would shed some light on the situation. If you look at the docs, you'll end up at OptionParser#make_switch
where you'll find an explanation of what the opt.on
arguments look like:
Long style switch:
Specifies a long style switch which takes a mandatory, optional or no argument. It’s a string of the following form:"--switch=MANDATORY" or "--switch MANDATORY" "--switch[=OPTIONAL]" "--switch"
Short style switch:
Specifies short style switch which takes a mandatory, optional or no argument. It’s a string of the following form:"-xMANDATORY" "-x[OPTIONAL]" "-x"
Note the -xMANDATORY
and then look closer at your @opts.on
call:
@opts.on( '-?', '-help','Show this message') do
# ---------------^^^^^
That -help
defines a -h
option with a required elp
argument. Presumably the option parser is interpreting that to mean that -h
is an alias for -?
and since -h
is defined with a required argument, -?
also requires an argument. If you use --help
(i.e. a long style switch) then you'll probably have a better time:
@opts.on('-?', '--help', 'Show this message') do
I working from the Ruby 2.0 version but I doubt much has changed in the option parser since the older version of Ruby that you appear to be using.