Решение на Трета задача - Четене на командни аргументи от Никола Жишев

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

Към профила на Никола Жишев

Резултати

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

Код

class CommandParser
attr_reader :command_name, :arguments, :options,
:options_with_parameter, :values, :options_help
def initialize(command_name)
@command_name = command_name
@arguments = []
@options = {}
@options_with_parameter = {}
@values = []

Тука ме мързеше да подавам стойностите навсякъде по-долу в кода при парсърите за отделните неща. Та реших, че при #parse ще е хубаво да си взимам стойностите в тази инстанция и да си построя гетъри за стойностите на аргументите, опциите и опциите с параметри, построени върху тази инстанционна променлива. Малко фийдбак дали така е по-добре, или да го бях оставил с предаване на value навсякъде?

Аз бих предпочел да ги подавам или по някакъв друг начин да се оправям с това. Така като ги променяш на всеки кол трябва да помня, че си ги променил преди да ги извикаш. Иначе ползвай поне argv като в условието, че в началото се чудех какво е това.

@options_help = []
end
def argument(name, &block)
arguments << [name, block]
end
def option(short_name, name, desc, &block)
set_options(options, short_name, name, block)
options_help << " -#{short_name}, --#{name} #{desc}\n"
end
def option_with_parameter(short_name, name, desc, argument, &block)
set_options(options_with_parameter, short_name, name, block)
options_help << " -#{short_name}, --#{name}=#{argument} #{desc}\n"
end
def set_options(options_to_set, short_name, name, block)
options_to_set["--#{name}"] = block
options_to_set["-#{short_name}"] = block
end
def parse(runner, values)
@values = values
parse_arguments(runner)
parse_options(runner)
parse_options_with_parameter(runner)
end
def help
argument_help + options_help.join
end
private
def argument_help
"Usage: #{command_name} #{arguments.map { |n, _y| "[#{n}]" }.join(' ')}\n"
end
def parse_arguments(runner)
arguments.zip(argument_values).each { |(_n, b), v| b.call(runner, v) }
end
def parse_options(runner)
option_values.each { |value| options[value].call(runner, true) }
end
def parse_options_with_parameter(runner)
option_with_parameter_values.each do |value|
option, val = value.split('=')
options_with_parameter[option].call(runner, val)
end
end
def argument_values
values.reject { |x| x.include? '-' }
end
def option_values
values.reject { |x| !x.include?('-') || x.include?('=') }
end
def option_with_parameter_values
values.reject { |x| !x.include? '=' }
end
end

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

.....F.FFF...F.

Failures:

  1) CommandParser#option_with_parameter parses a option with parameter in short format
     Failure/Error: parser.parse(command_runner, %w(-stime))
     NoMethodError:
       undefined method `call' for nil:NilClass
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `block in parse_options'
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `each'
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `parse_options'
     # /tmp/d20161113-27983-1bsq094/solution.rb:36:in `parse'
     # /tmp/d20161113-27983-1bsq094/spec.rb:87: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 basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
       
       expected: "Usage: ls"
            got: "Usage: ls \n"
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -Usage: ls
       +Usage: ls 
     # /tmp/d20161113-27983-1bsq094/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)>'

  3) 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-1bsq094/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)>'

  4) 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-1bsq094/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)>'

  5) CommandParser when having options with and without values and parameters parses all the options and arguments correctly
     Failure/Error: parser.parse(command_runner, %w(--all -d -ssize first.rb second.rb))
     NoMethodError:
       undefined method `call' for nil:NilClass
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `block in parse_options'
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `each'
     # /tmp/d20161113-27983-1bsq094/solution.rb:55:in `parse_options'
     # /tmp/d20161113-27983-1bsq094/solution.rb:36:in `parse'
     # /tmp/d20161113-27983-1bsq094/spec.rb:169: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.01064 seconds
15 examples, 5 failures

Failed examples:

rspec /tmp/d20161113-27983-1bsq094/spec.rb:83 # CommandParser#option_with_parameter parses a option with parameter in short format
rspec /tmp/d20161113-27983-1bsq094/spec.rb:103 # CommandParser#help shows basic usage message
rspec /tmp/d20161113-27983-1bsq094/spec.rb:107 # CommandParser#help shows single argument
rspec /tmp/d20161113-27983-1bsq094/spec.rb:113 # CommandParser#help shows multiple arguments
rspec /tmp/d20161113-27983-1bsq094/spec.rb:168 # CommandParser when having options with and without values and parameters parses all the options and arguments correctly

История (2 версии и 4 коментара)

Никола обнови решението на 08.11.2016 14:40 (преди над 7 години)

+class CommandParser
+ attr_reader :command_name, :arguments, :options,
+ :options_with_parameter, :values, :options_help
+
+ def initialize(command_name)
+ @command_name = command_name
+ @arguments = []
+ @options = {}
+ @options_with_parameter = {}
+ @values = []

Тука ме мързеше да подавам стойностите навсякъде по-долу в кода при парсърите за отделните неща. Та реших, че при #parse ще е хубаво да си взимам стойностите в тази инстанция и да си построя гетъри за стойностите на аргументите, опциите и опциите с параметри, построени върху тази инстанционна променлива. Малко фийдбак дали така е по-добре, или да го бях оставил с предаване на value навсякъде?

+ @options_help = []
+ end
+
+ def argument(name, &block)
+ arguments << [name, block]
+ end
+
+ def option(short_name, name, desc, &block)
+ set_options(options, short_name, name, block)
+ options_help << " -#{short_name}, --#{name} #{desc}\n"
+ end
+
+ def option_with_parameter(short_name, name, desc, argument, &block)
+ set_options(options_with_parameter, short_name, name, block)
+ options_help << " -#{short_name}, --#{name}=#{argument} #{desc}\n"
+ end
+
+ def set_options(options_to_set, short_name, name, block)
+ options_to_set["--#{name}"] = block
+ options_to_set["-#{short_name}"] = block
+ end
+
+ def parse(runner, values)
+ @values = values
+ parse_arguments(runner)
+ parse_options(runner)
+ parse_options_with_parameter(runner)
+ end
+
+ def help
+ argument_help + options_help.join
+ end
+
+ private
+
+ def argument_help
+ "Usage: #{command_name} #{arguments.map { |n, _y| "[#{n}]" }.join(' ')}\n"
+ end
+
+ def argument_values
+ values.reject { |x| x.include? '-' }
+ end
+
+ def parse_arguments(runner)
+ arguments.zip(argument_values).each { |(_n, b), v| b.call(runner, v) }
+ end
+
+ def option_values
+ values.reject { |x| !x.include?('-') || x.include?('=') }
+ end
+
+ def parse_options(runner)
+ option_values.each { |value| options[value].call(runner, true) }
+ end
+
+ def option_with_parameter_values
+ values.reject { |x| !x.include? '=' }
+ end
+
+ def parse_options_with_parameter(runner)
+ option_with_parameter_values.each do |value|
+ option, val = value.split('=')
+ options_with_parameter[option].call(runner, val)
+ end
+ end
+end

Никола обнови решението на 08.11.2016 14:49 (преди над 7 години)

class CommandParser
attr_reader :command_name, :arguments, :options,
:options_with_parameter, :values, :options_help
def initialize(command_name)
@command_name = command_name
@arguments = []
@options = {}
@options_with_parameter = {}
@values = []

Аз бих предпочел да ги подавам или по някакъв друг начин да се оправям с това. Така като ги променяш на всеки кол трябва да помня, че си ги променил преди да ги извикаш. Иначе ползвай поне argv като в условието, че в началото се чудех какво е това.

@options_help = []
end
def argument(name, &block)
arguments << [name, block]
end
def option(short_name, name, desc, &block)
set_options(options, short_name, name, block)
options_help << " -#{short_name}, --#{name} #{desc}\n"
end
def option_with_parameter(short_name, name, desc, argument, &block)
set_options(options_with_parameter, short_name, name, block)
options_help << " -#{short_name}, --#{name}=#{argument} #{desc}\n"
end
def set_options(options_to_set, short_name, name, block)
options_to_set["--#{name}"] = block
options_to_set["-#{short_name}"] = block
end
def parse(runner, values)
@values = values
parse_arguments(runner)
parse_options(runner)
parse_options_with_parameter(runner)
end
def help
argument_help + options_help.join
end
private
def argument_help
"Usage: #{command_name} #{arguments.map { |n, _y| "[#{n}]" }.join(' ')}\n"
end
- def argument_values
- values.reject { |x| x.include? '-' }
- end
-
def parse_arguments(runner)
arguments.zip(argument_values).each { |(_n, b), v| b.call(runner, v) }
end
- def option_values
- values.reject { |x| !x.include?('-') || x.include?('=') }
- end
-
def parse_options(runner)
option_values.each { |value| options[value].call(runner, true) }
end
- def option_with_parameter_values
- values.reject { |x| !x.include? '=' }
- end
-
def parse_options_with_parameter(runner)
option_with_parameter_values.each do |value|
option, val = value.split('=')
options_with_parameter[option].call(runner, val)
end
end
-end
+
+ def argument_values
+ values.reject { |x| x.include? '-' }
+ end
+
+ def option_values
+ values.reject { |x| !x.include?('-') || x.include?('=') }
+ end
+
+ def option_with_parameter_values
+ values.reject { |x| !x.include? '=' }
+ end
+end