How to use getoptlong class in ruby?
Asked Answered
H

2

6

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
Handful answered 16/4, 2011 at 18:39 Comment(1)
begin/end inside a begin/end while 1 block? o_O How about loop?Virgule
K
10

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, for ARGV[0] to be nil there will be no more arguments, so ARGV.empty? would probably suffice.
Kerbela answered 16/4, 2011 at 21:1 Comment(1)
optparser > getoptlong. Definitely.Virgule
W
0

you have several errors in the sample program

  1. #each and #get only return the first string in the option and convert the others to it.
  2. You should put that check for arguments before the options processing
  3. 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
Wasson answered 17/7, 2018 at 5:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.