Ruby, OptionParser and multiple flags

  • Thread starter LDC - Jairo Eduardo Lopez
  • Start date
L

LDC - Jairo Eduardo Lopez

Hello all,

I'm currently writing a small script needed for my lab in which I need to
parse a few command line arguments in a UNIX like way.

My code goes something like this:

#####
#!/usr/bin/ruby -w

require 'optparse'
require 'ostruct'

opciones = OpenStruct.new
opts = OptionParser.new do |opts|
opts.on("-u USER", "--uid USER", "UID del usuario.") do |usr|
opciones.user = usr
end

opts.on("-h HOST", "--host HOST", String, "Especifica el servidor.
Puede ser IP o DNS.") do |h|
opciones.host = h
end

opts.on("-p PORT", "--port PORT", Integer, "Especifica el puerto del
servidor. Debe ser entero.") do |p|
opciones.port = p
end
end

begin
opts.parse!(ARGV)
rescue Exception => e
puts e, opts
exit!
end

#####

When I run the script I run into the problem that if I use various flags,
and forget to put in the required arguments, some flags are taken as
arguments. I've read that if I use the coding I've used all three
flags, the argument should be obligatory.

To better explain, I'll give some examples:

-----
/script.rb -h
missing argument: -h
-----
Works fine.

-----
/script.rb -p
missing argument: -p
-----
Works fine.

-----
/script.rb -h -p
-----
The script accepts -p as the argument for -h, which shouldn't happen as -p
is actually a flag.

I'm not sure what the problem is so I need help.

I'm running on a Debian Etch Box i686 with a Ruby 1.8.5 version.

Any help would be greatly appreciated. Thank you all.
 
A

ara.t.howard

Hello all,

I'm currently writing a small script needed for my lab in which I
need to parse a few command line arguments in a UNIX like way.

My code goes something like this:

#####
#!/usr/bin/ruby -w

require 'optparse'
require 'ostruct'

opciones = OpenStruct.new
opts = OptionParser.new do |opts|
opts.on("-u USER", "--uid USER", "UID del usuario.") do |usr|
opciones.user = usr
end

opts.on("-h HOST", "--host HOST", String, "Especifica el
servidor. Puede ser IP o DNS.") do |h|
opciones.host = h
end

opts.on("-p PORT", "--port PORT", Integer, "Especifica el
puerto del servidor. Debe ser entero.") do |p|
opciones.port = p
end
end

begin
opts.parse!(ARGV)
rescue Exception => e
puts e, opts
exit!
end

#####

When I run the script I run into the problem that if I use various
flags, and forget to put in the required arguments, some flags are
taken as arguments. I've read that if I use the coding I've used
all three flags, the argument should be obligatory.

To better explain, I'll give some examples:

-----
./script.rb -h
missing argument: -h
-----
Works fine.

-----
./script.rb -p
missing argument: -p
-----
Works fine.

-----
./script.rb -h -p -----
The script accepts -p as the argument for -h, which shouldn't
happen as -p is actually a flag.

I'm not sure what the problem is so I need help.

you've told the option parser that -h accepts an argument and you've
given it one. there is no restriction that arguments must not start
with a '-' so, in this case, your code is doing it exactly what you
told it to do ;-)


-a
 
L

LDC - Jairo Eduardo Lopez

you've told the option parser that -h accepts an argument and you've given it
one. there is no restriction that arguments must not start with a '-' so, in
this case, your code is doing it exactly what you told it to do ;-)


-a

Fair enough. I thought that OptionParser looked out for that sort of
thing. Is there anyone who can point me in a direction so that I can try
and avoid that sort of confusion between arguments?
 
N

Nobuyoshi Nakada

Hi,

At Fri, 25 May 2007 01:13:54 +0900,
LDC - Jairo Eduardo Lopez wrote in [ruby-talk:252822]:
If -h can omit the argument,

opts.on("-h [HOST]", "--host", String, "Especifica el servidor.",
"Puede ser IP o DNS.") do |h|
opciones.host = h
end

Else, if it must not start with "-", you can restrict it with a
Regexp:

opts.on("-h HOST", "--host", /[^-].*/, "Especifica el servidor.",
"Puede ser IP o DNS.") do |h|
opciones.host = h
end

/(?!-).+/ results same as above.
 
R

Robert Klemme

Fair enough. I thought that OptionParser looked out for that sort of
thing. Is there anyone who can point me in a direction so that I can try
and avoid that sort of confusion between arguments?

Well, if you specify type of parameters (for example an int) then maybe
OptionParser will do it for you (because "-foo" does not translate well
to an int). For string arguments you can easily check yourself, like

raise ArgumentError, "No proper option value" if /^-/ =~ value

There is no way to automate that via OptionParser because it cannot know
what values you want it to accept. I am not sure whether you can
actually provide a regexp that OptionParser will test your argument
against - if that feature is there you could easily implement this
safety check.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top