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

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

Към профила на Виктор Маринов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 14 успешни тест(а)
  • 1 неуспешни тест(а)

Код

class CommandParser
def initialize(command)
@command = command
@args = []
@options = []
end
def argument(name, &block)
@args << Argument.new(name, &block)
end
def option(*args, &block)
@options << Option.new(*args, &block)
end
def option_with_parameter(*args, &block)
@options << OptionWithParameter.new(*args, &block)
end
def parse(command_runner, argv)
execute_args(command_runner, argv.reject { |a| a.include? '-' })
execute_options(command_runner, argv.select { |o| o.include? '-' })
end
def help
"Usage: #{@command} #{@args.map(&:help).join(' ')}" +
@options.map(&:help).join("")
end
private
def execute_args(command_runner, args)
@args.zip(args) { |arg, value| arg.call(command_runner, value) }
end
def execute_options(command_runner, options)
@options.each { |opt| opt.parse(command_runner, options) }
end
end
class Argument
attr_accessor :name
def initialize(name, &block)
@name = name
@block = block
end
def call(command_runner, value)
@block.call(command_runner, value)
end
def help
"[#{@name}]"
end
end
class Option
SPACES_COUNT = 4
attr_accessor :short_name, :full_name, :description
def initialize(short_name, full_name, description, &block)
@short_name = short_name
@full_name = full_name
@description = description
@block = block
end
def call(command_runner, value = true)
@block.call(command_runner, value)
end
def parse(command_runner, options)
call(command_runner) if options.any? { |opt| matches?(opt) }
end
def help
"\n#{' ' * SPACES_COUNT}-#{@short_name}, #{full_name_to_s} #{description}"
end
def full_name_to_s
"--#{full_name}"
end
private
def matches?(option)
key = option.tr('-', '')
key == @short_name || key == @full_name
end
end
class OptionWithParameter < Option
def initialize(short_name, full_name, description, value_name, &block)
super(short_name, full_name, description, &block)
@value_name = value_name
end
def full_name_to_s
"--#{full_name}=#{@value_name}"
end
def parse(command_runner, options)
options.each do |opt|
key, value = get_pair(opt)
call(command_runner, value) if matches?(key)
end
end
private
def get_pair(option)
if option.count('-') == 1
[option[1], option[2..-1]]
else
key, _, value = option.partition('=')
[key.tr('-', ''), value]
end
end
end

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

.......F.......

Failures:

  1) CommandParser#help shows basic usage message
     Failure/Error: expect(parser.help).to eq 'Usage: ls'
       
       expected: "Usage: ls"
            got: "Usage: ls "
       
       (compared using ==)
     # /tmp/d20161113-27983-8hys94/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)>'

Finished in 0.00978 seconds
15 examples, 1 failure

Failed examples:

rspec /tmp/d20161113-27983-8hys94/spec.rb:103 # CommandParser#help shows basic usage message

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

Виктор обнови решението на 09.11.2016 10:29 (преди около 8 години)

+class CommandParser
+ def initialize(command)
+ @command = command
+ @args = []
+ @options = []
+ end
+
+ def argument(name, &block)
+ @args << Argument.new(name, &block)
+ end
+
+ def option(*args, &block)
+ @options << Option.new(*args, &block)
+ end
+
+ def option_with_parameter(*args, &block)
+ @options << OptionWithParameter.new(*args, &block)
+ end
+
+ def parse(command_runner, argv)
+ execute_args(command_runner, argv.reject { |a| a.include? '-' })
+ execute_options(command_runner, argv.select { |o| o.include? '-' })
+ end
+
+ def help
+ "Usage: #{@command} #{@args.map(&:help).join(' ')}\n" +
+ @options.map(&:help).join("\n")
+ end
+
+ private
+
+ def execute_args(command_runner, args)
+ @args.zip(args) { |arg, value| arg.call(command_runner, value) }
+ end
+
+ def execute_options(command_runner, options)
+ @options.each { |opt| opt.parse(command_runner, options) }
+ end
+end
+
+class Argument
+ attr_accessor :name
+
+ def initialize(name, &block)
+ @name = name
+ @block = block
+ end
+
+ def call(command_runner, value)
+ @block.call(command_runner, value)
+ end
+
+ def help
+ "[#{@name}]"
+ end
+end
+
+class Option
+ SPACES_COUNT = 4
+ attr_accessor :short_name, :full_name, :description
+
+ def initialize(short_name, full_name, description, &block)
+ @short_name = short_name
+ @full_name = full_name
+ @description = description
+ @block = block
+ end
+
+ def call(command_runner, value = true)
+ @block.call(command_runner, value)
+ end
+
+ def parse(command_runner, options)
+ call(command_runner) if options.any? { |opt| matches?(opt) }
+ end
+
+ def help
+ "#{' ' * SPACES_COUNT}-#{@short_name}, #{full_name_to_s} #{description}"
+ end
+
+ def full_name_to_s
+ "--#{full_name}"
+ end
+
+ private
+
+ def matches?(option)
+ key = option.tr('-', '')
+ key == @short_name || key == @full_name
+ end
+end
+
+class OptionWithParameter < Option
+ def initialize(short_name, full_name, description, value_name, &block)
+ super(short_name, full_name, description, &block)
+ @value_name = value_name
+ end
+
+ def full_name_to_s
+ "--#{full_name}=#{@value_name}"
+ end
+
+ def parse(command_runner, options)
+ options.each do |opt|
+ key, value = get_pair(opt)
+ call(command_runner, value) if matches?(key)
+ end
+ end
+
+ private
+
+ def get_pair(option)
+ if option.count('-') == 1
+ [option[1], option[2..-1]]
+ else
+ key, _, value = option.partition('=')
+ [key.tr('-', ''), value]
+ end
+ end
+
+ def matches?(option)
+ key = option.tr('-', '')
+ key == @short_name || key == @full_name
+ end
+end

Виктор обнови решението на 09.11.2016 10:33 (преди около 8 години)

class CommandParser
def initialize(command)
@command = command
@args = []
@options = []
end
def argument(name, &block)
@args << Argument.new(name, &block)
end
def option(*args, &block)
@options << Option.new(*args, &block)
end
def option_with_parameter(*args, &block)
@options << OptionWithParameter.new(*args, &block)
end
def parse(command_runner, argv)
execute_args(command_runner, argv.reject { |a| a.include? '-' })
execute_options(command_runner, argv.select { |o| o.include? '-' })
end
def help
"Usage: #{@command} #{@args.map(&:help).join(' ')}\n" +
@options.map(&:help).join("\n")
end
private
def execute_args(command_runner, args)
@args.zip(args) { |arg, value| arg.call(command_runner, value) }
end
def execute_options(command_runner, options)
@options.each { |opt| opt.parse(command_runner, options) }
end
end
class Argument
attr_accessor :name
def initialize(name, &block)
@name = name
@block = block
end
def call(command_runner, value)
@block.call(command_runner, value)
end
def help
"[#{@name}]"
end
end
class Option
SPACES_COUNT = 4
attr_accessor :short_name, :full_name, :description
def initialize(short_name, full_name, description, &block)
@short_name = short_name
@full_name = full_name
@description = description
@block = block
end
def call(command_runner, value = true)
@block.call(command_runner, value)
end
def parse(command_runner, options)
call(command_runner) if options.any? { |opt| matches?(opt) }
end
def help
"#{' ' * SPACES_COUNT}-#{@short_name}, #{full_name_to_s} #{description}"
end
def full_name_to_s
"--#{full_name}"
end
private
def matches?(option)
key = option.tr('-', '')
key == @short_name || key == @full_name
end
end
class OptionWithParameter < Option
def initialize(short_name, full_name, description, value_name, &block)
super(short_name, full_name, description, &block)
@value_name = value_name
end
def full_name_to_s
"--#{full_name}=#{@value_name}"
end
def parse(command_runner, options)
options.each do |opt|
key, value = get_pair(opt)
call(command_runner, value) if matches?(key)
end
end
private
def get_pair(option)
if option.count('-') == 1
[option[1], option[2..-1]]
else
key, _, value = option.partition('=')
[key.tr('-', ''), value]
end
end
-
- def matches?(option)
- key = option.tr('-', '')
- key == @short_name || key == @full_name
- end
end

Виктор обнови решението на 09.11.2016 15:48 (преди около 8 години)

class CommandParser
def initialize(command)
@command = command
@args = []
@options = []
end
def argument(name, &block)
@args << Argument.new(name, &block)
end
def option(*args, &block)
@options << Option.new(*args, &block)
end
def option_with_parameter(*args, &block)
@options << OptionWithParameter.new(*args, &block)
end
def parse(command_runner, argv)
execute_args(command_runner, argv.reject { |a| a.include? '-' })
execute_options(command_runner, argv.select { |o| o.include? '-' })
end
def help
- "Usage: #{@command} #{@args.map(&:help).join(' ')}\n" +
- @options.map(&:help).join("\n")
+ "Usage: #{@command} #{@args.map(&:help).join(' ')}" +
+ @options.map(&:help).join("")
end
private
def execute_args(command_runner, args)
@args.zip(args) { |arg, value| arg.call(command_runner, value) }
end
def execute_options(command_runner, options)
@options.each { |opt| opt.parse(command_runner, options) }
end
end
class Argument
attr_accessor :name
def initialize(name, &block)
@name = name
@block = block
end
def call(command_runner, value)
@block.call(command_runner, value)
end
def help
"[#{@name}]"
end
end
class Option
SPACES_COUNT = 4
attr_accessor :short_name, :full_name, :description
def initialize(short_name, full_name, description, &block)
@short_name = short_name
@full_name = full_name
@description = description
@block = block
end
def call(command_runner, value = true)
@block.call(command_runner, value)
end
def parse(command_runner, options)
call(command_runner) if options.any? { |opt| matches?(opt) }
end
def help
- "#{' ' * SPACES_COUNT}-#{@short_name}, #{full_name_to_s} #{description}"
+ "\n#{' ' * SPACES_COUNT}-#{@short_name}, #{full_name_to_s} #{description}"
end
def full_name_to_s
"--#{full_name}"
end
private
def matches?(option)
key = option.tr('-', '')
key == @short_name || key == @full_name
end
end
class OptionWithParameter < Option
def initialize(short_name, full_name, description, value_name, &block)
super(short_name, full_name, description, &block)
@value_name = value_name
end
def full_name_to_s
"--#{full_name}=#{@value_name}"
end
def parse(command_runner, options)
options.each do |opt|
key, value = get_pair(opt)
call(command_runner, value) if matches?(key)
end
end
private
def get_pair(option)
if option.count('-') == 1
[option[1], option[2..-1]]
else
key, _, value = option.partition('=')
[key.tr('-', ''), value]
end
end
end