Optparse "invalid option" problem

Hi,

'optparse' seems to continue parsing even after the first invalid argument.

example.rb:

require 'optparse'

ARGV.options do |opts|
   opts.separator "Required:"
   opts.on("-f", "--ffmpeg PATH", String, "ffmpeg's path") { |val| ffmpeg = val }
end

leftOver = ARGV.parse!
p leftOver

> example.rb -f ./ffmpeg Tool/to/call/from/example.rb

works as expected (leftOver contains "Tool/to/call/from/example.rb"), but

> example.rb -f ./ffmpeg Tool/to/call/from/example.rb --toolsOption value

raises "invalid option: --toolsOption"

instead of pushing "Tool/to/call/from/example.rb", "--toolsOption" and "value" into leftOver

Is there a way to tell optparse that everything after the first unknown argument is ignored and pushed into the resulting array?

Thanks!

   Michael

Michael Keller wrote:

Hi,

Hello,

'optparse' seems to continue parsing even after the first invalid argument.

example.rb:

require 'optparse'

ARGV.options do |opts|
  opts.separator "Required:"
  opts.on("-f", "--ffmpeg PATH", String, "ffmpeg's path") { |val| ffmpeg
= val }
end

leftOver = ARGV.parse!
p leftOver

example.rb -f ./ffmpeg Tool/to/call/from/example.rb

works as expected (leftOver contains "Tool/to/call/from/example.rb"), but

example.rb -f ./ffmpeg Tool/to/call/from/example.rb --toolsOption value

raises "invalid option: --toolsOption"

instead of pushing "Tool/to/call/from/example.rb", "--toolsOption" and
"value" into leftOver

That's how it's supposed to work: you can catch the error, or ...

Is there a way to tell optparse that everything after the first unknown
argument is ignored and pushed into the resulting array?

Not automatically, but you can try:

example.rb -f ./ffmpeg Tool/to/call/from/example.rb -- --toolsOption\ value

=> ["Tool/to/call/from/example.rb", "--toolsOption", "value"]

or you can quote the argument as a whole and split it later:

example.rb -f ./ffmpeg Tool/to/call/from/example.rb "--toolsOption\ value"

=> ["Tool/to/call/from/example.rb --toolsOption value"]

HTH,

t.

···

--
Anton Bangratz - Key ID 363474D1 - http://tony.twincode.net/
fortune(6):
It would save me a lot of time if you just gave up and went mad now.

Hi tony,

if I use order!() instead of parse!() then it works the way I need

I took a look in optparse.rb (that's why i love open source :slight_smile: :

  def parse!(argv = ARGV)
     if ENV.include?('POSIXLY_CORRECT')
       order!(argv)
     else
       permute!(argv)
     end
   end

and POSIXLY_CORRECT' is not set on my system...

Thanks for your help.

   Michael

Hi,

At Wed, 31 May 2006 01:03:56 +0900,
Anton 'tony' Bangratz wrote in [ruby-talk:195197]:

>> example.rb -f ./ffmpeg Tool/to/call/from/example.rb
>
> works as expected (leftOver contains "Tool/to/call/from/example.rb"), but
>
>
>> example.rb -f ./ffmpeg Tool/to/call/from/example.rb --toolsOption value
>
> raises "invalid option: --toolsOption"
>
> instead of pushing "Tool/to/call/from/example.rb", "--toolsOption" and
> "value" into leftOver

optparse has two modes, permutation and in-order. It is
permutation mode by default, and in-order mode if the
environment variable POSIXLY_CORRECT is set.

> Is there a way to tell optparse that everything after the first unknown
> argument is ignored and pushed into the resulting array?

ARGV.order!

···

--
Nobu Nakada

And here's how I did it, not bothering to look at the source

( warning: Excessive sillyness follows)

% cat oparse.rb
args = ARGV.dup
cc = callcc { |x| x }
begin
   old_verbose = $VERBOSE
   $VERBOSE = nil
   require 'optparse'
ensure
   $VERBOSE = old_verbose
end

ARGV.options do |opts|
   opts.separator "Required:"
   opts.on("-f", "--ffmpeg PATH", String, "ffmpeg's path") { |val| ffmpeg = val }
end

begin
leftOver = ARGV.parse!
rescue OptionParser::InvalidOption => ex
i = nil
args.each_with_index do |v, idx|
    if v == ex.args.first
      i = idx
      break
    end
end

args.insert(i, "--")
begin
    old_verbose = $VERBOSE
    $VERBOSE = nil
    ARGV = args
ensure
    $VERBOSE = old_verbose
end
$LOADED_FEATURES.delete('optparse.rb')
cc.call
end

p leftOver

% ruby oparse.rb
["Tool/to/call/from/example.rb", "--toolsOption", "value"]

···

On May 30, 2006, at 12:29 PM, Michael Keller wrote:

Hi tony,

if I use order!() instead of parse!() then it works the way I need

I took a look in optparse.rb (that's why i love open source :slight_smile: :

def parse!(argv = ARGV)
    if ENV.include?('POSIXLY_CORRECT')
      order!(argv)
    else
      permute!(argv)
    end
  end

and POSIXLY_CORRECT' is not set on my system...

Thanks for your help.

  Michael