Александър обнови решението на 09.11.2016 00:07 (преди около 8 години)
+class Argument
+ attr_reader :name
+ def initialize(name, block)
+ @name = name
+ @block = block
+ end
+
+ def call(runner, value)
+ @block.call(runner, value)
+ end
+end
+
+class Option
+ attr_reader :short, :long, :description
+ def initialize(short, long, description, block)
+ @short = short
+ @long = long
+ @description = description
+ @block = block
+ end
+
+ def call(runner)
+ @block.call(runner, true)
+ end
+
+ def check?(name)
+ name == @short || name == @long
+ end
+end
+
+class OptionWithParameter
+ attr_reader :short, :long, :description, :placeholder
+ def initialize(short, long, description, placeholder, block)
+ @short = short
+ @long = long
+ @description = description
+ @placeholder = placeholder
+ @block = block
+ end
+
+ def check?(name)
+
+ name == @short || name == @long
+ end
+
+ def call(runner, value)
+ @block.call(runner, value)
+ end
+end
+
+def read_options_with_parameter(command_runner, options_with_parameter)
+ options_with_parameter.each do |name|
+ if name[1] == '-'
+ parts = name.split('=')
+ else
+ name_of_the_option = name.slice(0..1)
+ value = name.slice(2..-1)
+ parts = [name_of_the_option, value]
+ end
+ option_with_parameter_block_call(command_runner, parts)
+ end
+end
+
+def remove_dashes(options)
+ options.each do |opt|
+ opt.slice!(0) if opt.chr == '-'
+ opt.slice!(0) if opt.chr == '-'
+ end
+end
+
+ def call_methods(command_runner, argv)
+ options = argv.select { |x| x.start_with?('-') && !x.include?('.rb') }
+ options_with_parameter =
+ argv.select { |x| x.start_with?('-') && x.include?('.rb') }
+ read_options(command_runner, options)
+ read_options_with_parameter(command_runner, options_with_parameter)
+ arguments = argv - options - options_with_parameter
+ read_arguments(command_runner, arguments)
+ end
+
+ def option_with_parameter_block_call(command_runner, parts)
+ remove_dashes(parts)
+ matching = @option_with_parameter.select { |opt| opt.check?(parts[0]) }
+ matching[0].call(command_runner, parts[1]) unless matching.empty?
+ end
+
+ def read_options(command_runner, options)
+ remove_dashes(options)
+ options.each do |name|
+ matching = @options.select { |opt| opt.check?(name) }
+ matching[0].call(command_runner) unless matching.empty?
+ end
+ end
+
+ def read_arguments(command_runner, arguments)
+ @arguments.zip(arguments).each do |arg, value|
+ arg.call(command_runner, value)
+ end
+ end
+
+ def argument_pusher(array_arg)
+ @arguments.each do |arg|
+ array_arg.push("[#{arg.name}]")
+ end
+ end
+
+ def option_pusher(array_opt)
+ @options.each do |opt|
+ array_opt.push(" -#{opt.short}, --#{opt.long} #{opt.description}")
+ end
+ end
+
+ def option_with_parameter_pusher(array_param)
+ @option_with_parameter.each do |opt|
+ array_param.push(
+ " -#{opt.short}, --#{opt.long}=#{opt.placeholder} #{opt.description}"
+ )
+ end
+ end
+class CommandParser
+ def initialize(name)
+ @name = name
+ @arguments = []
+ @options = []
+ @option_with_parameter = []
+ end
+
+ def argument(name, &block)
+ @arguments.push(Argument.new(name, block))
+ end
+
+ def option(short, long, description, &block)
+ @options.push(Option.new(short, long, description, block))
+ end
+
+ def option_with_parameter(short, long, description, placeholder, &block)
+ @option_with_parameter
+ .push(OptionWithParameter
+ .new(short, long, description, placeholder, block)
+ )
+ end
+
+ def help
+ array_arg = []
+ array_opt = []
+ array_param = []
+ argument_pusher(array_arg)
+ option_pusher(array_opt)
+ option_with_parameter_pusher(array_param)
+ "Usage: #{@name} #{array_arg.join(" ")}\r\n"\
+ "#{array_opt.join(" ")}\r\n"\
+ "#{array_param.join(" ")}"
+ end
+
+ def parse(command_runner, argv)
+ call_methods(command_runner, argv)
+ end
+end