Project

General

Profile

Actions

Bug #10021

closed

OptParse does not handle missing arguments bracketed by valid option switches

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

Status:
Closed
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.

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']

Actions

Also available in: Atom PDF

Like0
Like0Like0