please help me with OptionParser

  • Thread starter Christopher J. Bottaro
  • Start date
C

Christopher J. Bottaro

Here's the pastebin of this post if you prefer looking at formatted
source:
http://pastebin.ca/514353

Ok, I'm having a multitude of problems with OptionParser. First, I
can't get it to work following the online documentation.

Second, I got it to work by adding :REQUIRED to the on() method call,
but that doesn't work as expected: the argument isn't really
"required"; OptionParser does not bomb if the argument is omitted.

Third, I cannot get a switch to accept multiple arguments.
--my_arg 1 2 3
I want an array [1, 2, 3].

Thanks for the help, the rest of the message contains my pastebin
post:

!/usr/bin/env ruby

require 'optparse'
require 'ostruct'

options = OpenStruct.new
options.client_ids = []
options.save = false

op = OptionParser.new do |opts|
opts.on("-c", "--client", "client id to migrate for") { |client_id|
options.client_ids << client_id }

opts.on_tail("-h", "--help", "Show this message") { puts opts;
exit }
end

begin
op.parse!
rescue Exception => e
puts op
puts e
exit
end

puts options

# ruby script.rb --client 123
# #<OpenStruct client_ids=[true], save=false>

# if I change on() to be:
opts.on("-c", "--client", Integer "client id to migrate for") { |
client_id| options.client_ids << client_id }
# then, ruby script.rb --client 123
# #<OpenStruct client_ids=[nil], save=false>

# furthermore it works if I change on() to be:
opts.on("-c", "--client", :REQUIRED, Integer "client id to migrate
for") { |client_id| options.client_ids << client_id }
# then, ruby script.rb --client 123
# #<OpenStruct client_ids=[123], save=false>
# which is correct, but if I run, ruby script.rb, it does not bomb out
saying it's missing a required argument.
# and still furthermore, I can't do something like this: ruby
script.rb --client 123 456
# and get #<OpenStruct client_ids=[123, 456], save=false>
 
A

Axel Etzold

Dear all,

I am trying to get Jeff Mitchell's linalg package
to work on my machine (OpenSuse 10.2 on i586).
I installed the linalg-0.3.2-i686-linux-ruby18.tgz package,
apparently successfully (that's what my computer told me),

but when I try to actually use it, I get:
require "linalg"

/usr/local/lib/ruby/site_ruby/1.8/x86_64-linux/lapack.so: /usr/local/lib/ruby/site_ruby/1.8/x86_64-linux/lapack.so: wrong ELF class: ELFCLASS32 - /usr/local/lib/ruby/site_ruby/1.8/x86_64-linux/lapack.so (LoadError)
from /usr/local/lib/ruby/site_ruby/1.8/linalg.rb:7
from test.rb:1:in `require'
from test.rb:1

I also tried to compile the other linalg.tgz package from source,
but there, the system misses f2c, and can't be told to find it in
/usr/bin, or to compile with the flag --without-libf2c .

Thank you for any help.

Best regards,

Axel
 
C

Christopher J. Bottaro

Ugh, you replied on my message and screwed up my thread on Google
Groups... and anyone else who uses a thread aware mail/news program.
 
A

Axel Etzold

Dear Christopher,

I am sorry about this . It won't happen again.

Best regards,

Axel
 
S

Stefano Crocco

Alle domenica 27 maggio 2007, Christopher J. Bottaro ha scritto:
Second, I got it to work by adding :REQUIRED to the on() method call,
but that doesn't work as expected: =A0the argument isn't really
"required"; OptionParser does not bomb if the argument is omitted.

=46rom a previous thread on the list=20
(http://www.ruby-forum.com/topic/49989#16302), I gather what you want to do=
=20
is impossible with OptionParser (but it may be possible with other librarie=
s:=20
I've never used them so I can't tell). To achieve what you mean, you should=
=20
check whether the option was given or not yourself, looking at the variable=
=20
where you stored the options:

if options.client_ids.empty?
puts "You must specify an ID"
exit
end
Third, I cannot get a switch to accept multiple arguments.
--my_arg 1 2 3
I want an array [1, 2, 3].

I don't think you can write a list of that kind, because OptionParser would=
=20
treat every argument as a single option. You can specify more than one=20
argument to an option, but you need to separe them with commas, not with=20
spaces. If you do that, you can convert the result to an Array by specifyin=
g=20
it:

opts.on("--list", Array, "a test list){|a| options.list =3D a}

I hope this helps

Stefano
 
C

Christopher J. Bottaro

Alle domenica 27 maggio 2007, Christopher J. Bottaro ha scritto:
Second, I got it to work by adding :REQUIRED to the on() method call,
but that doesn't work as expected: the argument isn't really
"required"; OptionParser does not bomb if the argument is omitted.

From a previous thread on the list
(http://www.ruby-forum.com/topic/49989#16302), I gather what you want to do
is impossible with OptionParser (but it may be possible with other libraries:
I've never used them so I can't tell). To achieve what you mean, you should
check whether the option was given or not yourself, looking at the variable
where you stored the options:

if options.client_ids.empty?
puts "You must specify an ID"
exit
end
Third, I cannot get a switch to accept multiple arguments.
--my_arg 1 2 3
I want an array [1, 2, 3].

I don't think you can write a list of that kind, because OptionParser would
treat every argument as a single option. You can specify more than one
argument to an option, but you need to separe them with commas, not with
spaces. If you do that, you can convert the result to an Array by specifying
it:

opts.on("--list", Array, "a test list){|a| options.list = a}

I hope this helps

Stefano

Thank you, Stefano, yes it did help.
 
J

Jeremy Hinegardner

--dc+cDN39EJAMEtIO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Here's the pastebin of this post if you prefer looking at formatted
source:
http://pastebin.ca/514353

Ok, I'm having a multitude of problems with OptionParser. First, I
can't get it to work following the online documentation.

Which online documentation are you using?

http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html

That's the documentation that I use.
Second, I got it to work by adding :REQUIRED to the on() method call,
but that doesn't work as expected: the argument isn't really
"required"; OptionParser does not bomb if the argument is omitted.

That's not actually how you do it. The style to code up a required
argument is:

opts.on("-c", "--client ID", "client id to migrate for")

Putting something after the option tells option parser that you
require an argument on that option. In this cases putting ID after
--client tells the parser that this option has a required argument.
use [ID] to designate option parameters.

To force ID to be an integer, you can change the option to be:

opts.on("-c", "--client ID", Integer, "client id to migrate for")
...

This will make sure that ID is an Integer before passing to the block.
If it isn't it will throw and exception.
Third, I cannot get a switch to accept multiple arguments.
--my_arg 1 2 3
I want an array [1, 2, 3].

Array style arguments are done as comma separated items that are passed
to the block as an Array. So ch

opts.on("-c", "--client ID,ID", Array, "client id(s) to migrate for")
...

In your case, it seems you want to make sure that the option parameters
to ID is an Array of Integers. Which means you'll have to tweak it a
bit for yourself. I've written up one solution in the attached .rb
file.
Thanks for the help, the rest of the message contains my pastebin
post:

Play with the attached test cases and make it do what you want. I made
tests to describe what you wanted, and the Application class that is
tested meets those test.

enjoy,

-jeremy

--
========================================================================
Jeremy Hinegardner (e-mail address removed)


--dc+cDN39EJAMEtIO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="integer-array-options.rb"

#!/usr/bin/env ruby
require 'optparse'
require 'ostruct'
require 'test/unit'

class OptionParserTestApplication

attr_accessor :eek:ptions

def initialize
@options = default_options
@parser = option_parser

end
def run(argv = [])
begin
@parser.parse!(argv)
rescue OptionParser::parseError => pe
puts pe
puts @parser
exit 1
end
end

def default_options
op = OpenStruct.new
op.client_ids = []
op.save = false
return op
end

def option_parser
OptionParser.new do |opts|
opts.on("-c", "--client ID,LIST", Array,"client id to migrate for") do |client_id_list|
client_id_list.each do |cid|
begin
@options.client_ids << Integer(cid)
rescue ArgumentError => e
raise OptionParser::parseError, "#{cid} is not an integer"
end
end
end

opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end
end
end

class TestOptions < Test::Unit::TestCase

def setup
@app = OptionParserTestApplication.new
end

def test_client_id_required
argv = %w(--client)
assert_raise(SystemExit) { @app.run(argv) }
end

def test_client_ids_are_integer
argv = %w(--client 123)
@app.run(argv)
assert_equal(123,@app.options.client_ids.first)
end

def test_client_ids_as_array
argv = %w(--client 123,456)
@app.run(argv)
assert_equal(2,@app.options.client_ids.size)
assert(@app.options.client_ids.include?(123))
assert(@app.options.client_ids.include?(456))
end

def test_client_ids_as_array_of_integers
argv = %w(--client 123,not-a-number)
assert_raise(SystemExit) { @app.run(argv) }
end
end

--dc+cDN39EJAMEtIO--
 
A

Allison Newman

I'm no expert, I've only used OptionParser for simple command parsing,
but looking at the documentation, to read an array, you probably need to
do something like this:

opts.on("--clients x,y,z", Array, "Example 'list' of arguments") do
|list|
options.client_ids = list
end
 

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

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top