Решение на Трета задача - Четене на командни аргументи от Кристъфър Коруев

Обратно към всички решения

Към профила на Кристъфър Коруев

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 12 успешни тест(а)
  • 3 неуспешни тест(а)

Код

class Option
attr_accessor :short, :long, :description
def initialize(short, long, description, placeholder)
@short = '-' + short
@long = '--' + long
@description = description
@placeholder = placeholder
end
def to_str
return " #{@short}, #{@long} #{@description}" if @placeholder.nil?
" #{@short}, #{@long}=#{@placeholder} #{@description}"
end
def self.get_option_value(option)
return option.split('=')[1] if option.split('=').length == 2
is_short_with_value = option.length > 2 && !Option.long?(option)
return option.slice(2, option.length) if is_short_with_value
true
end
def self.get_option_name(option)
return option.slice(0, 2) if Option.short?(option)
return option.split('=')[0] if Option.long?(option)
end
def self.long?(option)
option.start_with?('--') && option.length > 2
end
def self.short?(option)
option.slice(0, 2).start_with?('-') && option.slice(0, 2) != '--'
end
end
class CommandParser
def initialize(name)
@name = name
@argument_blocks = {}
@option_blocks = {}
@arguments = []
@options = []
@option_objects = []
end
def argument(name, &block)
@argument_blocks[name] = block
end
def option(short, long, description, &block)
add_option(short, long, description, nil, &block)
end
def option_with_parameter(short, long, description, placeholder, &block)
add_option(short, long, description, placeholder, &block)
end
def parse(command_runner, argv)
init_options_and_arguments(argv)
@argument_blocks.values.each do |argument_block|
argument_block.call(command_runner, @arguments.shift)
end
@options.each do |option|
value = Option.get_option_value(option)
block = @option_blocks[Option.get_option_name(option)]
block.call(command_runner, value) unless block.nil?
end
end
def help
usage_message = 'Usage: ' + @name
@argument_blocks.keys.each do |key|
usage_message += " [#{key}]"
end
usage_message += "\n"
option_message = ""
@option_objects.each do |option|
option_message += option.to_str + "\n"
end
usage_message + option_message
end
private
def add_option(short, long, description, placeholder, &block)
option = Option.new(short, long, description, placeholder)
@option_blocks[option.short] = block
@option_blocks[option.long] = block
@option_objects.push(option)
end
def init_options_and_arguments(argv)
@options.clear
@arguments.clear
argv.each do |arg|
if arg.start_with?('-')
@options.push(arg)
else
@arguments.push(arg)
end
end
end
end

Лог от изпълнението

.......FFF.....

Failures:

  1) CommandParser#help shows basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
       
       expected: "Usage: ls"
            got: "Usage: ls\n"
       
       (compared using ==)
       
       Diff:
     # /tmp/d20161113-27983-bbb0tb/spec.rb:104:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) CommandParser#help shows single argument
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FILE]'
       
       expected: "Usage: ls [FILE]"
            got: "Usage: ls [FILE]\n"
       
       (compared using ==)
       
       Diff:
     # /tmp/d20161113-27983-bbb0tb/spec.rb:110:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) CommandParser#help shows multiple arguments
     Failure/Error: expect(parser.help).to eq 'Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]'
       
       expected: "Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]"
            got: "Usage: ls [FIRST FILE] [SECOND FILE] [THIRD FILE]\n"
       
       (compared using ==)
       
       Diff:
     # /tmp/d20161113-27983-bbb0tb/spec.rb:118:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.00893 seconds
15 examples, 3 failures

Failed examples:

rspec /tmp/d20161113-27983-bbb0tb/spec.rb:103 # CommandParser#help shows basic usage message
rspec /tmp/d20161113-27983-bbb0tb/spec.rb:107 # CommandParser#help shows single argument
rspec /tmp/d20161113-27983-bbb0tb/spec.rb:113 # CommandParser#help shows multiple arguments

История (1 версия и 0 коментара)

Кристъфър обнови решението на 09.11.2016 00:24 (преди около 8 години)

+class Option
+ attr_accessor :short, :long, :description
+
+ def initialize(short, long, description, placeholder)
+ @short = '-' + short
+ @long = '--' + long
+ @description = description
+ @placeholder = placeholder
+ end
+
+ def to_str
+ return " #{@short}, #{@long} #{@description}" if @placeholder.nil?
+ " #{@short}, #{@long}=#{@placeholder} #{@description}"
+ end
+
+ def self.get_option_value(option)
+ return option.split('=')[1] if option.split('=').length == 2
+ is_short_with_value = option.length > 2 && !Option.long?(option)
+ return option.slice(2, option.length) if is_short_with_value
+ true
+ end
+
+ def self.get_option_name(option)
+ return option.slice(0, 2) if Option.short?(option)
+ return option.split('=')[0] if Option.long?(option)
+ end
+
+ def self.long?(option)
+ option.start_with?('--') && option.length > 2
+ end
+
+ def self.short?(option)
+ option.slice(0, 2).start_with?('-') && option.slice(0, 2) != '--'
+ end
+end
+
+class CommandParser
+ def initialize(name)
+ @name = name
+ @argument_blocks = {}
+ @option_blocks = {}
+ @arguments = []
+ @options = []
+ @option_objects = []
+ end
+
+ def argument(name, &block)
+ @argument_blocks[name] = block
+ end
+
+ def option(short, long, description, &block)
+ add_option(short, long, description, nil, &block)
+ end
+
+ def option_with_parameter(short, long, description, placeholder, &block)
+ add_option(short, long, description, placeholder, &block)
+ end
+
+ def parse(command_runner, argv)
+ init_options_and_arguments(argv)
+ @argument_blocks.values.each do |argument_block|
+ argument_block.call(command_runner, @arguments.shift)
+ end
+
+ @options.each do |option|
+ value = Option.get_option_value(option)
+ block = @option_blocks[Option.get_option_name(option)]
+ block.call(command_runner, value) unless block.nil?
+ end
+ end
+
+ def help
+ usage_message = 'Usage: ' + @name
+ @argument_blocks.keys.each do |key|
+ usage_message += " [#{key}]"
+ end
+ usage_message += "\n"
+ option_message = ""
+ @option_objects.each do |option|
+ option_message += option.to_str + "\n"
+ end
+ usage_message + option_message
+ end
+
+ private
+
+ def add_option(short, long, description, placeholder, &block)
+ option = Option.new(short, long, description, placeholder)
+ @option_blocks[option.short] = block
+ @option_blocks[option.long] = block
+ @option_objects.push(option)
+ end
+
+ def init_options_and_arguments(argv)
+ @options.clear
+ @arguments.clear
+ argv.each do |arg|
+ if arg.start_with?('-')
+ @options.push(arg)
+ else
+ @arguments.push(arg)
+ end
+ end
+ end
+end