Кузман обнови решението на 08.11.2016 18:15 (преди около 8 години)
+class CommandParser
+ attr_accessor :command_name, :objects, :arguments, :options
+
+ def initialize(command_name)
+ @command_name = command_name
+ @objects = []
+ @arguments = []
+ @options = []
+ end
+
+ def argument(arg_name, &block)
+ new_argument = Argument.new(arg_name, &block)
+ objects << new_argument
+ arguments << new_argument
+ end
+
+ def option(short_name, full_name, help, &block)
+ new_option = Option.new(short_name, full_name, help, &block)
+ objects << new_option
+ options << new_option
+ end
+
+ def option_with_parameter(*params, &block)
+ new_option = OptionWithArgument.new(*params, &block)
+ objects << new_option
+ options << new_option
+ end
+
+ def parse(command_runner, argv)
+ i = 0
+ argv.each do |arg|
+ if objects[i] && objects[i].valid?(arg)
+ objects[i].parse(command_runner, arg)
+ i += 1
+ end
+ end
+ end
+
+ def help
+ result = "Usage: #{command_name}"
+ (arguments + options).each { |obj| result += obj.help }
+ result
+ end
+end
+
+# < Something
+class Argument
+ attr_accessor :arg_name, :block, :names
+
+ def initialize(arg_name, &block)
+ @arg_name = arg_name
+ @block = block
+ end
+
+ def parse(command_runner, argv)
+ block.call(command_runner, argv)
+ end
+
+ def help
+ " [#{arg_name}]"
+ end
+
+ def valid?(value)
+ value[/^[^-]/]
+ end
+end
+
+class Option
+ attr_accessor :short_name, :full_name, :help_msg, :block, :names
+
+ def initialize(*params, &block)
+ @short_name = params[0]
+ @full_name = params[1]
+ @help_msg = params[2]
+ @block = block
+ end
+
+ def parse(command_runner, argv)
+ if argv.length == 2 && short_name == argv[1]
+ block.call(command_runner, true)
+ elsif argv.length > 2 && full_name == argv[2..-1]
+ block.call(command_runner, true)
+ end
+ end
+
+ def help
+ "\n -#{short_name}, --#{full_name} #{help_msg}"
+ end
+
+ def valid?(value)
+ names.include?(value)
+ end
+
+ private
+
+ def names
+ ["--#{full_name}", "-#{short_name}"]
+ end
+end
+
+class OptionWithArgument
+ attr_accessor :short_name, :full_name, :help_msg, :parameter, :block, :names
+
+ def initialize(short_name, full_name, help_msg, parameter, &block)
+ @short_name = "-#{short_name}"
+ @full_name = "--#{full_name}"
+ @help_msg = help_msg
+ @parameter = parameter
+ @block = block
+ end
+
+ def parse(command_runner, argv)
+ if argv.start_with?(full_name)
+ value = argv.split("#{full_name}=")[1]
+ option = full_name
+ elsif argv.start_with?(short_name)
+ value = argv.split(short_name)[1]
+ option = short_name
+ end
+ block.call(command_runner, value) if names.include?(option)
+ end
+
+ def help
+ "\n #{short_name}, #{full_name}=#{parameter} #{help_msg}"
+ end
+
+ def valid?(value)
+ names.any? { |valid_name| value.start_with? valid_name }
+ end
+
+ private
+
+ def names
+ [full_name, short_name]
+ end
+end