Петър обнови решението на 09.11.2016 03:46 (преди около 8 години)
+class CommandParser
+ def initialize(command_name)
+ @command_name = command_name
+ @arguments = []
+ @options = []
+ end
+
+ def argument(argument, &block)
+ @arguments << Argument.new(argument, &block)
+ end
+
+ def option(sname, lname, help, &block)
+ @options << Option.new(sname, lname, help, &block)
+ end
+
+ def option_with_parameter(sname, lname, help, dependency, &block)
+ @options << OptionWithParam.new(sname, lname, help, dependency, &block)
+ end
+
+ def parse(command_runner, argv)
+ argv = parse_argv(argv)
+ parse_arguments(command_runner, argv[1])
+ argv[0].each { |el| parse_options(command_runner, el) }
+ end
+
+ def help
+ print 'Usage: '
+ @arguments.each { |arg| print arg }
+ puts ""
+ @options.each { |opt| puts opt }
+ end
+
+ private
+ def parse_options(command_runner, name)
+ @options.each { |opt| opt.execute_block(command_runner, name) }
+ end
+
+ def parse_arguments(command_runner, argument_values)
+ i = 0
+ @arguments.each do |arg|
+ arg.execute_block(command_runner, argument_values[i])
+ i += 1
+ end
+ end
+
+ def parse_argv(argv)
+ out = []
+ out[0] = argv.select { |element| element.include?('-') }
+ out[1] = argv.reject { |element| element.include?('-') }
+ out
+ end
+end
+
+class Argument
+ def initialize(name, &block)
+ @name = name
+ @block = block
+ end
+ attr_reader :name
+
+ def execute_block(command_runner, argvalue)
+ @block.call(command_runner, argvalue)
+ end
+
+ def to_s
+ '[' + name + ']'
+ end
+end
+
+class Option
+ def initialize(sname, lname, help, &block)
+ @sname = '-' + sname
+ @lname = '--' + lname
+ @help = help
+ @block = block
+ end
+ attr_reader :sname
+ attr_reader :lname
+ attr_reader :help
+
+ def execute_block(command_runner, _)
+ @block.call(command_runner, true)
+ end
+
+ def to_s
+ " " + sname + ", " + lname + " " + help
+ end
+end
+
+class OptionWithParam < Option
+ def initialize(sname, lname, help, dependency, &block)
+ @sname = '-' + sname
+ @lname = '--' + lname + "=" + dependency
+ @help = help
+ @dependency = dependency
+ @block = block
+ end
+ attr_reader :dependency
+
+ def execute_block(command_runner, argvalue)
+ argvalue = parse_name(argvalue)
+ @block.call(command_runner, argvalue)
+ end
+
+ private
+ def parse_name(name)
+ if name.include?('=')
+ name.split('=')[1]
+ else
+ name[2..-1]
+ end
+ end
+end