I’m wrapping a bunch of scripts with an command-line program, and I’m
wanting to use OptionParser to grab some of the options for the wrapper
application. Can anyone tell me if it’s possible to rescue all the
invalid
options for the wrapper application such that I can leave them in ARGV
so
they’re available to my scripts when I load them?
At Wed, 20 Feb 2008 10:00:17 +0900,
Bryan R. wrote in [ruby-talk:291710]:
I’m wrapping a bunch of scripts with an command-line program, and I’m
wanting to use OptionParser to grab some of the options for the wrapper
application. Can anyone tell me if it’s possible to rescue all the invalid
options for the wrapper application such that I can leave them in ARGV so
they’re available to my scripts when I load them?
OptionParser raises an OptionParser::InvalidOption, which has
erred option in args.
others = []
ARGV.options do |opt|
opt.on("–foo=BAR") {|foo| puts “foo option #{foo}”}
begin
opt.parse!
rescue OptionParser::InvalidOption => e
others.concat(e.args)
end
end
exec(“your command”, *ohters)
It uses an undocumented feature: the .options attribute of ARGV.
It uses the try/except mechanism which slows down your program when a
exception actually occurs.
The fact that an option might not be a wrapper option is not an
exceptional event–you regularly expect that to be the case.
It requires that you use a user defined array in place of ARGV.
Here’s another solution:
require ‘optparse’
p ARGV
puts
opts = OptionParser.new do |opts|
#wrapper option where value is required:
opts.on("-t=RANDOM_CHARS") do |val|
puts “-t option entered with value=#{val}”
opt_index = ARGV.index('-t')
#delete option and its value:
ARGV.delete_at(opt_index) #rest of elements move one spot to the
left
ARGV.delete_at(opt_index)
end
#wrapper option where value is optional:
opts.on("-y [=RANDOM_CHARS]") do |val| #val==nil if no value for
option
puts “-y option entered with value=#{val}”
opt_index = ARGV.index('-y')
ARGV.delete_at(opt_index)
if val
ARGV.delete_at(opt_index)
end
end
#non-wrapper option:
opts.on("-a=RANDOM_CHARS") do |val|
puts “-a option entered with value=#{val}”
end
end
opts.parse(ARGV)
p ARGV
Problems with that solution:
I’m not thrilled with the code that deletes elements out of ARGV–that’s
inefficient because the rest of the elements have to be shuffled over
one spot. On the other hand, if I collect all the desired options into
an array and then assign the array to ARGV, I get a warning:
It uses the try/except mechanism which slows down your program when a
exception actually occurs.
Options are only parsed once per invocation. The exception time is
easily dominated by process exec time and the runtime of the wrapped
program.
The fact that an option might not be a wrapper option is not an
exceptional event–you regularly expect that to be the case.
Well, but from OptionParser’s perspective it is an exception: the
option is unkown to OptionParser and hence it cannot process properly.
I do agree though that it is a bit odd, especially considering that
all other options still are parsed properly which might not
necessarily be expected (I would expect OptionParser to bail out at
the first unknown option by default).
Problems with that solution:
I’m not thrilled with the code that deletes elements out of ARGV–that’s
inefficient because the rest of the elements have to be shuffled over
one spot. On the other hand, if I collect all the desired options into
an array and then assign the array to ARGV, I get a warning:
warning: already initialized constant ARGV
Another issue I see with your solution is that you might run into
problems because you remove items from a collection that is being
iterated over. That’s usually unsafe.
This on is a bit artificial: by using ARGV.index to find an option
your code assumes that OptionParser will process options left to
right. If it chooses a different approach you might end up deleting
the wrong instance of a duplicated option.
It uses the try/except mechanism which slows down your program when a
exception actually occurs.
Options are only parsed once per invocation. The exception time is
easily dominated by process exec time and the runtime of the wrapped
program.
Options are only parsed once per invocation.
What’s an invocation, and what’s that go to do with anything?
The exception time is
easily dominated by process exec time and the runtime of the wrapped
program.
I don’t know what that means. Are you saying that if the program runs
for an hour, the extra exception processing time only takes an
additional 15 seconds?
What’s an invocation, and what’s that go to do with anything?
Process invocation in this case.
The exception time is
easily dominated by process exec time and the runtime of the wrapped
program.
I don’t know what that means. Are you saying that if the program runs
for an hour, the extra exception processing time only takes an
additional 15 seconds?
Apart from the fact that processing a single exception uses less than
15 seconds, yes. The exception processing time is negligible compared
to the time necessary for exec and for running the wrapped program.
How do you know there won’t be 40 million exceptions? Would process
exec time and the runtime of the wrapped program dominate the exception
time in that case?
Yes, because you get at most 1 exception per process invocation - so
there must be 40 million process invocations which are several orders
of magnitude more expensive than the exception processing.
What’s an invocation, and what’s that go to do with anything?
Process invocation in this case.
The exception time is
easily dominated by process exec time and the runtime of the wrapped
program.
I don’t know what that means. Are you saying that if the program runs
for an hour, the extra exception processing time only takes an
additional 15 seconds?
Apart from the fact that processing a single exception uses less than
15 seconds, yes.
How do you know there won’t be 40 million exceptions? Would process
exec time and the runtime of the wrapped program dominate the exception
time in that case?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.