#ruby #getopt-long
#ruby #getopt-длинный
Вопрос:
Мне нужна помощь в использовании класса getoptlong в Ruby. Мне нужно выполнить команду prog_name.ruby -u -i -s filename. Пока я могу выполнить его только с помощью prog_name.ruby -u filename -i filename -s filename.
Это мой код getoptlong:
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
Комментарии:
1.
begin/end
внутриbegin/end while 1
блока? o_O Как насчетloop
?
Ответ №1:
Я собираюсь ответить, порекомендовав взглянуть на новый драгоценный камень «slop«. Это оболочка вокруг getoptlong
.
Вы можете использовать, gem install slop
если вы используете RVM, или sudo gem install slop
иначе.
GetOptLong очень мощный, но, хотя я использовал его несколько раз, мне все равно приходится каждый раз просматривать документы.
Если вам нужно немного больше мощности с «более простым в использовании интерфейсом, чем GetOptLong», загляните в Ruby OptionParser
. Вам нужно будет лучше проработать логику, но это быстрый способ преобразования вашего кода. Мне пришлось удалить класс для CommonLog gem, потому что я им не пользуюсь. Важный материал следует за строкой, из которой извлекается журнал 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!
Кроме того, в качестве краткой критики, вы не пишете идиоматический код Ruby:
when
инструкции могут быть записаны:when "-h", "--help"
if ARGV[0] == nil || ARGV.size != 1
является запутанным. Узнайте, как работают ARGV и массивы. Обычно дляARGV[0]
значения nil больше не будет аргументов, так чтоARGV.empty?
этого, вероятно, будет достаточно.
Комментарии:
1. optparser > getoptlong. Определенно.
Ответ №2:
у вас есть несколько ошибок в примере программы
- #each и #get возвращают только первую строку в опции и преобразуют в нее остальные.
- Вы должны установить эту проверку для аргументов перед обработкой параметров
- Вы, вероятно, не хотите, чтобы это было в вашем классе ведения журнала
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