Bug #10021
closedOptParse does not handle missing arguments bracketed by valid option switches
Description
OS=CentOS-6.5 x86_64
Ruby=2.1.2p95
I have this in an optparse structure:
# Create parser
opts = OptionParser.new do |opts|
opts.banner = <<-BANNER
. . .
opts.on("-r", "--rerun=DATEorTRANSACTION", "--re-run=DATEorTRANSACTION",
"Re-run extract for specific date (yyyymmdd)",
" or transaction number (SSSSSNNNNNNNNC).",
" Multiple specifications are ORed for selections.",
" All billable transactions are selectable",
" whether previously billed or not.",
" Sets and enforces --no-update" ) do |rr|
options.rerun << rr
options.update = false
end
. . .
If I run a program incorporating this option class so:
--re-run x --rerun y -r
Then I see this:
missing argument: -r
However, if I do this:
--re-run x --rerun y -r --debug
or this
--re-run x -r --rerun y
Then the program runs and does not report the missing argument.
Is this the intended behaviour? It does not seem correct to me.
Updated by byrnejb (James Byrne) over 10 years ago
When I try this:
--re-run x -r --rerun y -- file
Then I see this
:in `eval': Only one output filename is permitted (RuntimeError)
From which I infer that -r has 'eaten' --rerun as its argument and OptsParse is treating y as the file name (args[0]) I exposed the structures with a debug routine and this is what they show:
--debug --re-run x -r --rerun y -- file
Options before parsing with --debug
Number of arguments passed: 8
Arguments passed are:
---
- "--debug"
- "--re-run"
- x
- "-r"
- "--rerun"
- y
- "--"
- file
Argument object contains:
["--debug", "--re-run", "x", "-r", "--rerun", "y", "--", "file"]
bin/hll_th_hp_billing_extract:67:in `eval': Only one output filename is permitted (RuntimeError)
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Status changed from Open to Closed
I believe this is the intended behavior. You are using a required argument for the -r
option, so for --re-run x --rerun y -r --debug
the -r
option arguments are ['x', 'y', '--debug']
, with no regular arguments. For --re-run x -r --rerun y
, the -r
option arguments are ['x', '--rerun']
, with remaining arguments ['y']
. For --re-run x -r --rerun y -- file
, the -r
option arguments are ['x', '--rerun']
, with remaining arguments ['y', 'file']
It sounds like you want to use an optional argument:
opts.on("-r", "--rerun [DATEorTRANSACTION]", "--re-run [DATEorTRANSACTION]"){|rr|}
With an optional argument, for --re-run x --rerun y -r --debug
the '-r' option arguments are ['x', 'y', nil]
, with a --debug
option and no regular arguments. For --re-run x -r --rerun y
, the -r
option arguments are ['x', nil, 'y']
, with no remaining arguments. For --re-run x -r --rerun y -- file
, the -r
option arguments are ['x', nil, 'y']
, with remaining arguments ['file']