Ралица обнови решението на 04.11.2016 17:11 (преди около 8 години)
+
+module ParseMethods
+ def parse_option(value, command_runner)
+ if value.start_with?("--")
+ parse_full_name_options(value, command_runner)
+ else
+ parse_short_options(value, command_runner)
+ end
+ end
+
+ def parse_full_option_with_parameter(value, command_runner)
+ elements = value.split("=", 2)
+ if @option_with_parameter.keys.include? (elements[0])
+ @option_with_parameter[elements[0]][0].call(command_runner, elements[1])
+ end
+ end
+
+ def parse_full_name_options(value, command_runner)
+ value = value.delete "-"
+ if value.include? '='
+ parse_full_option_with_parameter(value, command_runner)
+ elsif @options.keys.include? value
+ @options[value][0].call(command_runner, true)
+ end
+ end
+
+ def parse_short_options_with_parameter(value, command_runner)
+ elements = value.split(//, 2)
+ index = @option_with_parameter.values.find_index do |item|
+ item[1] == elements[0]
+ end
+ if index != nil
+ key = @option_with_parameter.keys[index]
+ @option_with_parameter[key][0].call(command_runner, elements[1])
+ end
+ end
+
+ def parse_short_options_without_parameter(value, command_runner)
+ index = @options.values.find_index { |item| item[1] == value }
+ if index != nil
+ key = @options.keys[index]
+ @options[key][0].call(command_runner, true)
+ end
+ end
+
+ def parse_short_options(value, command_runner)
+ value = value.delete "-"
+ if value.length > 1
+ parse_short_options_with_parameter(value, command_runner)
+ else
+ parse_short_options_without_parameter(value, command_runner)
+ end
+ end
+
+end
+
+class CommandParser
+
+ include ParseMethods
+
+ def initialize(command_name)
+ @command_name = command_name
+ @arguments = {}
+ @options = {}
+ @option_with_parameter = {}
+ end
+
+ def argument(argument_name, &block)
+ @arguments[argument_name] = block
+ end
+
+ def option(short_name, option_full_name, text, &block)
+ @options[option_full_name] = [block, short_name, text]
+ end
+
+ def option_with_parameter(short_name, full_name, text, option_name, &block )
+ @option_with_parameter[full_name] = [block, short_name, text, option_name]
+ end
+
+ def parse(command_runner, argv)
+ i = 0
+ argv.each do |value|
+ if value[0] != '-'
+ @arguments[@arguments.keys[i]].call(command_runner, value)
+ i += 1
+ else
+ parse_option(value, command_runner)
+ end
+ end
+ end
+
+ def help
+ message = 'Usage: ' + @command_name
+ @arguments.each { |name, _| message += ' [' + name + ']' }
+
+ @options.each do |name, info|
+ message += "\n" + ' -' + info[1] + ', --' + name + ' ' + info[2]
+ end
+
+ @option_with_parameter.each do |name, info|
+ message += "\n" + ' -' + info[1] + ', --' + name + '=' + info[3]
+ message += ' ' + info[2]
+ end
+ message
+ end
+end