How do you specify a required switch (not argument) with Ruby OptionParser?

前端 未结 8 2071
时光取名叫无心
时光取名叫无心 2020-12-12 23:58

I\'m writing a script and I want to require a --host switch with value, but if the --host switch isn\'t specified, I want the option parsing to fai

8条回答
  •  -上瘾入骨i
    2020-12-13 00:36

    An approach using optparse that provides friendly output on missing switches:

    #!/usr/bin/env ruby
    require 'optparse'
    
    options = {}
    
    optparse = OptionParser.new do |opts|
      opts.on('-f', '--from SENDER', 'username of sender') do |sender|
        options[:from] = sender
      end
    
      opts.on('-t', '--to RECIPIENTS', 'comma separated list of recipients') do |recipients|
        options[:to] = recipients
      end
    
      options[:number_of_files] = 1
      opts.on('-n', '--num_files NUMBER', Integer, "number of files to send (default #{options[:number_of_files]})") do |number_of_files|
        options[:number_of_files] = number_of_files
      end
    
      opts.on('-h', '--help', 'Display this screen') do
        puts opts
        exit
      end
    end
    
    begin
      optparse.parse!
      mandatory = [:from, :to]                                         # Enforce the presence of
      missing = mandatory.select{ |param| options[param].nil? }        # the -t and -f switches
      unless missing.empty?                                            #
        raise OptionParser::MissingArgument.new(missing.join(', '))    #
      end                                                              #
    rescue OptionParser::InvalidOption, OptionParser::MissingArgument      #
      puts $!.to_s                                                           # Friendly output when parsing fails
      puts optparse                                                          #
      exit                                                                   #
    end                                                                      #
    
    puts "Performing task with options: #{options.inspect}"
    

    Running without the -t or -f switches shows the following output:

    Missing options: from, to
    Usage: test_script [options]
        -f, --from SENDER                username of sender
        -t, --to RECIPIENTS              comma separated list of recipients
        -n, --num_files NUMBER           number of files to send (default 1)
        -h, --help
    

    Running the parse method in a begin/rescue clause allows friendly formatting upon other failures such as missing arguments or invalid switch values, for instance, try passing a string for the -n switch.

提交回复
热议问题