I need help using getoptlong class in Ruby. I need to execute command prog_name.ruby -u -i -s filename. So far I can only execute it with prog_name.ruby -u filename -i filename -s filename.
This is my getoptlong code:
require 'getoptlong'
class CommonLog
parser = GetoptLong.new
parser.set_options(["-h", "--help", GetoptLong::NO_ARGUMENT],
["-u", "--url", GetoptLong::NO_ARGUMENT],
["-i", "--ip", GetoptLong::NO_ARGUMENT],
开发者_运维百科 ["-s", "--stat", GetoptLong::NO_ARGUMENT])
begin
begin
opt,arg = parser.get_option
break if not opt
case opt
when "-h" || "--help"
puts "Usage: -u filename"
puts "Usage: -i filename"
puts "Usage: -s filename"
exit
when "-u" || "--url"
log = CommonLog.new(ARGV[0])
log.urlReport
when "-i" || "--ip"
log = CommonLog.new(ARGV[0])
log.ipReport
when "-s" || "--stat"
log = CommonLog.new(ARGV[0])
log.statReport
end
rescue => err
puts "#{err.class()}: #{err.message}"
puts "Usage: -h -u -i -s filename"
exit
end
end while 1
if ARGV[0] == nil || ARGV.size != 1
puts "invalid! option and filename required"
puts "usage: -h -u -i -s filename"
end
I'm going to answer by recommending looking at the new-ish "slop" gem. It's a wrapper around getoptlong
.
You can use gem install slop
if you're using RVM, or sudo gem install slop
otherwise.
GetOptLong is very powerful but, though I've used it several times, I still have to go review the docs each time.
If you want a bit more power, with an "easier to use interface than GetOptLong", look into Ruby's OptionParser
. You'll need to work out the logic better, but this is a quick pass converting your code. I had to stub out a class for the CommonLog gem because I don't use it. The important stuff follows the line pulling log from ARGV
:
require 'optparse'
class CommonLog
def initialize(*args); end
def urlReport(); puts "running urlReport()"; end
def ipReport(); puts "running ipReport()"; end
def statReport(arg); puts "running statReport(#{arg})"; end
end
log = CommonLog.new(ARGV[0])
OptionParser.new { |opts|
opts.banner = "Usage: #{File.basename($0)} -u -i -s filename"
opts.on( '-u', '--[no-]url', 'some short text describing URL') do
log.urlReport()
end
opts.on('-i', '--[no-]ip', 'some short text describing IP') do
log.ipReport()
end
opts.on('-s', '--stat FILENAME', 'some short text describing STAT') do |arg|
log.statReport(arg)
end
}.parse!
Also, as a quick critique, you are not writing idiomatic Ruby code:
when
statements can be written:when "-h", "--help"
if ARGV[0] == nil || ARGV.size != 1
is convoluted. Study up on how ARGV and arrays work. Normally, forARGV[0]
to be nil there will be no more arguments, soARGV.empty?
would probably suffice.
you have several errors in the sample program
- #each and #get only return the first string in the option and convert the others to it.
- You should put that check for arguments before the options processing
- You probably don't want this in with your logging class
require 'getoptlong'
# don't pollute CommonLog with this
include CommonLog
# if this is the startup module
if __FILE__ == $0 then
# Check to ensure there are arguments
if ARGV.size < 1
puts "invalid! option and filename required"
puts "usage: -h -u -i -s filename"
end
# set up parser and get the options
parser_opts=GetoptLong.new(
["--help", "-h", GetoptLong::NO_ARGUMENT],
["--url", "-u", GetoptLong::NO_ARGUMENT],
["--ip", "-i", "--ip", GetoptLong::NO_ARGUMENT],
["--stat", "-s", GetoptLong::NO_ARGUMENT]
)
parser_opts.each do |opt,arg|
begin # this is for the exception processing
case opt
when "--help" #only the first option is returned read ruby doc on #each
puts "Usage: -u filename"
puts "Usage: -i filename"
puts "Usage: -s filename"
exit
when "--url" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.urlReport
when "--ip" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.ipReport
when "--stat" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.statReport
else # this should not be used
puts "unexpected option %s"%opt
puts "Usage: -h -u -i -s filename"
end
rescue Exception => err #rescuing an unexpected Exception
puts "#{err.class()}: #{err.message}"
puts "Usage: -h -u -i -s filename"
Kernel.exit
end
end
end
精彩评论