Project

General

Profile

Bug #10021

OptParse does not handle missing arguments bracketed by valid option switches

Added by byrnejb (James Byrne) over 5 years ago. Updated 4 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
Ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux-gnu]
[ruby-core:63614]

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.

History

Updated by byrnejb (James Byrne) over 5 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) 4 months 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']

Also available in: Atom PDF