Option Parser with an optional flag/switch for last argument

I am using OptionParser to parse command-line options. I would like to
run a program in following manner:

$ multiply-by.rb --factor 3 4
$ 12

where last number '4' is an input argument which should not need any
option flag/switch. Any hints on how can it be done? Is it possible with
OptionParser or should I write my own option parser method?

thanks,
N

···

--
Posted via http://www.ruby-forum.com/.

Yes, just use the ARGV as if you would without using OptionParser;
once it has parsed everything it recognizes, it will leave the rest of
arguments in ARGV.

-- Matma Rex

You could just access it directly in ARGV after parsing everything else
using OptionParser.

···

On Wed, May 16, 2012 at 12:03:07AM +0900, Neubyr Neubyr wrote:

I am using OptionParser to parse command-line options. I would like to
run a program in following manner:

$ multiply-by.rb --factor 3 4
$ 12

where last number '4' is an input argument which should not need any
option flag/switch. Any hints on how can it be done? Is it possible with
OptionParser or should I write my own option parser method?

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Thanks for the reply everyone. I am taking approach as suggested by
Bartosz and Chad to assign 'left-over' ARGV to the input decimal number.

@Mike, the commandable gem looks really useful. I am not using it right
now, but it looks like it will be useful in some of my other
projects/command-line apps. Thanks for providing a detailed example.

···

--
Posted via http://www.ruby-forum.com/.

This is how I'd do it:

require 'optparse'

factor = nil

OptionParser.new do |opts|
  opts.on '-f', '--factor=F', Integer, 'Multiplication factor' do |v|
    factor = v
  end
end.parse! ARGV

abort "ERROR: need a factor" unless factor

ARGV.each {|v| puts(Integer(v) * factor)}

Kind regards

robert

···

On Tue, May 15, 2012 at 5:03 PM, Neubyr Neubyr <lists@ruby-forum.com> wrote:

I am using OptionParser to parse command-line options. I would like to
run a program in following manner:

$ multiply-by.rb --factor 3 4
$ 12

where last number '4' is an input argument which should not need any
option flag/switch. Any hints on how can it be done? Is it possible with
OptionParser or should I write my own option parser method?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

You could also give Commandable a try (gem install commandable). Your
code might look something like this:

#!/usr/bin/env ruby
# file: MultiplyBy
require 'commandable'

class MultiplyBy
  extend Commandable

  command "multiply a set of numbers"
  def factor(*numbers)
    numbers.inject(1) {|memo, i| i.to_f * memo}
  end

end

Commandable.execute
# end

And you would run it like this:

$ ./MultiplyBy factor 3 4

12.0

No ugly "--" and you can even do more natural looking verbage like:

$ ./Multiply 3 by 4

12.0

Using code like:

#!/usr/bin/env ruby
require 'commandable'

class MultiplyBy
  extend Commandable

  command "the base number", :default, :required, priority: 1
  def number(base_number)
    @base_number = base_number.to_f
  end

  command "multiply a set of numbers by the base number"
  def by(*numbers)
    numbers.inject(@base_number) {|memo, i| puts "memo: #{memo}"; i.to_f * memo}
  end

end

Commandable.execute

···

On Tue, May 15, 2012 at 11:46 AM, Bartosz Dziewoński <matma.rex@gmail.com> wrote:

Yes, just use the ARGV as if you would without using OptionParser;
once it has parsed everything it recognizes, it will leave the rest of
arguments in ARGV.

-- Matma Rex

if you need flexibility, then ARGV by itself is more than enough.

eg, re your sample,
$ cat -n test2.rb
     1
     2 operator=ARGV.shift
     3
     4 ops=%w(* / + -)
     5
     6 if not (ops).include? operator
     7 raise "operator argument must be one of #{ops}"
     8 end
     9
    10 factors=ARGV
    11 if factors.size < 2
    12 raise "need at least two args for operator"
    13 end
    14
    15 factors=ARGV.map(&:to_f)
    16
    17 p factors.inject(operator.to_sym)
    18
    19
botp@u:~
$ ruby test2.rb - 3 4 5 #subtract
-6.0
botp@u:~
$ ruby test2.rb + 3 4 5 #add
12.0
botp@u:~
$ ruby test2.rb "*" 3 4 5 #multiply; need to quote
60.0

just a thought.
kind regards -botp

···

On Wed, May 16, 2012 at 5:56 AM, Neubyr Neubyr <lists@ruby-forum.com> wrote:

Thanks for the reply everyone. I am taking approach as suggested by
Bartosz and Chad to assign 'left-over' ARGV to the input decimal number.

@Mike, the commandable gem looks really useful. I am not using it right
now, but it looks like it will be useful in some of my other
projects/command-line apps. Thanks for providing a detailed example.