Ruby cli

From wikinotes

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]

    DESCRIPTION:
      says hello

    PARAMS:
      -n --name:
        assign a name

    EXAMPLE:
      #{EXECUTABLE} -n my-name

    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
    @shift = 0
    @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
    instance = self
    Enumerator.new do |enum|
      loop do
        break if @index >= @argv.count

        enum.yield([self, next_item])
      end
    end.each { |enumerator, val| yield(enumerator, val) }
  end
end


class CommandlineInterface
  Args = Struct.new(:name, :age)

  def help_msg
    <<~HELP
    #{EXECUTABLE} [-h]

    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}")