Ruby cli
From wikinotes
Some rough starting points for creating commandline interfaces in ruby.
salt to taste.
Param Parsing, Raw
no structure
#!/usr/bin/env ruby EXECUTABLE = File.basename(__FILE__) name = "unknown" age = "unknown" shift = 0 ARGV.count.times do |index| if shift > 0 shift -= 1 next end case ARGV[index] when '-h', '--help' helpmsg = <<~HELP #{EXECUTABLE} [-h] [-n NAME] [-a AGE] DESCRIPTION: says hello PARAMS: -n --name: assign a name -a --age: assign an age EXAMPLE: #{EXECUTABLE} -n my-name -a 30 HELP puts(helpmsg) exit(0) when '-n', '--name' name = ARGV[index+1] shift += 1 when '-a', '--age' age = ARGV[index+1] shift += 1 else puts "error" exit(1) end end puts("hello, #{name} with age #{age}")enumerator structure
#!/usr/bin/env ruby EXECUTABLE = File.basename(__FILE__) class ArgumentIterator def initialize(argv) @argv = argv @index = 0 end def shift(n = 1) n.times.map { next_item } end def next_item val = @argv[@index] @index += 1 val end def each Enumerator.new do |enum| loop do break if @index >= @argv.count enum.yield([self, next_item]) end end.each { |this, val| yield(this, val) } end end class CommandlineInterface Args = Struct.new(:name, :age) def help_msg <<~HELP #{EXECUTABLE} [-h] [-n NAME] [-a AGE] DESCRIPTION: says hello PARAMS: -n --name: assign a name -a --age: assign an age EXAMPLE: #{EXECUTABLE} -n my-name -a 30 HELP end def parse_args(argv) name = "unknown" age = "unknown" ArgumentIterator.new(argv).each do |iterator, arg| case arg when '-h', '--help' puts(help_msg) exit(0) when '-n', '--name' name, = iterator.shift when '-a', '--age' age, = iterator.shift else $stderr.puts("[ERROR] unexpected argument #{arg}") exit(1) end end Args.new(name, age) end end cli = CommandlineInterface.new args = cli.parse_args(ARGV) puts("hello, #{args.name} with age #{args.age}")
Optparse
Ruby ships also ships with option parser.
It works by defining a DSL for params (ex.opts.on("-n NAME", "--name NAME"
), and defining callbacks for each param.
I think it's a bit more complicated than it needs to be.Example from the docs:
require 'optparse' options = {} OptionParser.new do |parser| parser.on("-r", "--require LIBRARY", "Require the LIBRARY before executing your script") do |lib| puts "You required #{lib}!" end end.parse!