Трета задача вече е факт. Quack, quack!
Трета задача
-- Отговорих си на въпроса
@Лазар не си трий въпроса. Ако има неяснота е хубаво и другите да могат да погледнат тук ако не им е било ясно.
Въпросът ми беше какво прави метода
#argument
тъй като не го схванах съвсем, ноо мисля че разбрах.Не е голяма работа, но
Този клас трябва да има методи #argument, #option и #option_with_argument
, докато примерите и тестовете говорят заoption_with_parameter
.Имам и въпрос: Какви символи са позволени за имена на опции?
EDIT: В единия пример за help-a има следния формат:
parser.help #=> 'Usage: rspec [FIRST] [SECOND]'
, а малко по-надолу срещаме:'Usage: rspec [SPEC FILE]
. Кое да ползваме?В този пример
parser = CommandParser.new('rspec') parser.option('v', 'version', 'show version number') do |runner, value| runner[:version] = value end command_runner = {} parser.parse(command_runner, ['--version']) command_runner #=> {version: true}
Ако няма зададена такава опция, да връщаме ли само
{}
илиcommand_runner #=> {version: false}
@Михаил,
#option_with_parameter
е метода, който искаме за задачата.Късите имена на опциите ще са само една буква, докато дългите имена могат да имат произволна дължина, като няма да съдържат whitespace символи.
За
#help
виж примера пак. В първия пример имаме 2 аргумента'FIRST'
и'SECOND'
, във втория само един -'SPEC FILE'
.@Христина ако нямате дадена опция не се очаква да извикате блока за нея. В твоя пример
command_runner #=> {}
Имам въпрос как да форматирам крайния стринг на #help , по-точно как се слагат новите редове, тъй като ако сложа \n, като върна стринга стринга съдържа самия символ \n и тестовете не го отчитат като "properly formatted string "
Wasn't here
да направих всичко в Google , включително и изпозлвах "" вместо '' , но \n продължава да се връща като поредица от символи а не се интерпретира :(
п.С. Всичко си е било наред аз не съм догледал нещо, съжалявам.
Здравейте, в условието има следната забележка
Забележка: За по-просто, няма да тестваме с различен брой позиционни аргументи в argv от броя на дефинираните в нашия парсер. За сметка на това, може да има опции (нещата, започващи с тире), които да направят argv с различна дължина от броя на извикванията на argument.
Това означава ли, че случаи като по-долният ще бъдат изключени от тестовете?
parser = CommandParser.new('rspec') parser.argument('FIRST') do |runner, value| runner[:first] = value end parser.argument('SECOND') do |runner, value| runner[:second] = value end command_runner = {} parser.parse(command_runner, ['foo', 'larodi']) command_runner #=> {first: 'foo', second: 'larodi'} parser.parse(command_runner, ['test'])
Ако не съм разбрал правилно забележката, то тогава горният пример дали трябва да върне резултат
{first: 'foo', second: 'larodi', third: 'test'}
или резултатът трябва да е{first: 'test', second: 'larodi'}
?@Иван, никъде в кода няма
:third
. Откъде смяташ, че ще се появи? :)Забележката казва, че няма да подаваме
parser.parse(command_runner, ['test'])
ако сме извикали#argument
два пъти. Тоест, няма да правим това в примера ти.Георги, благодаря за бързия отговор и се извинявам за предния пост, имам пропуск във кода.. Хем го редактирах този пост няколко пъти :D имах предвид
parser = CommandParser.new('rspec') parser.argument('FIRST') do |runner, value| runner[:first] = value end parser.argument('SECOND') do |runner, value| runner[:second] = value end parser.argument('THIRD') do |runner, value| runner[:third] = value end command_runner = {} parser.parse(command_runner, ['foo', 'larodi']) command_runner #=> {first: 'foo', second: 'larodi'} parser.parse(command_runner, ['test'])
Извинявам се за неразбирането. Тоест дали може да има случаи на незапълнени аргументи и дали ако #parse бъде извикан втори път ще пълни тези аргументи, които все още нямат стойност или първият, който има стойност? Това не ми е напълно ясно, и такива примери ли няма да има? Благодаря и съжалявам за няколкото поста
@Иван
Забележка: За по-просто, няма да тестваме с различен брой позиционни аргументи в argv от броя на дефинираните в нашия парсер. За сметка на това, може да има опции (нещата, започващи с тире), които да направят argv с различна дължина от броя на извикванията на argument. Тоест броя на позиционните аргументи в argv ще е равен на броя на тези, които сме дефинирали.(В твоя случай 3)
@Иван каквото @Петко каза. Няма да тестваме с повече или по-малко позиционни аргументи от тези, които са дефинирани за парсъра. Също така повторното извикване не трябва да прави нищо специално. Имайте предвид, че на всяко извикване на
#parse
command_runner
-а, които му се подава може да е различен.Благодаря за отговорите, това е хубава новина! Съжалявам, за следващия въпрос, но за да съм 100% сигурен все пак ще го задам.
Възможно ли е
#argument
и#option_with_parameter
да са дефинирани със един и същи параметър? Например следния случай:parser.argument('FILE') do |runner, value| runner[:file] = value end parser.option_with_parameter('r', 'require', 'require FILE in spec', 'FILE') do |runner, value| runner[:file] = value end
Благодаря.
@Иван, възможно е. Трябва да имаш предвид, че така наречените "имена" на опции, аргументи и т.н. са там с цел да се генерира документацията.
@Марио, благодаря за бързият отговор. Значи в такъв случай, документацията ще включи 'FILE' като
Usage: rspec -r, --require=FILE require FILE in spec
а не като
Usage: rspec [FILE] -r, --require=FILE require FILE in spec
(в случая
parser = CommandParser.new('rspec')
)?parser = CommandParser.new('rspec') parser.argument('FILE') do |runner, value| runner[:file] = value end parser.option_with_parameter('r', 'require', 'require FILE in spec', 'FILE') do |runner, value| runner[:file] = value end
Ще ти върне това:
Usage: rspec [FILE] -r, --require=FILE require FILE in spec
И това, че имат еднакви имена няма никакво значение. Тези имена не са идентификатори под никаква форма.
Супер, благодаря!
Блоковете, които се подават на #argument, #option и #option_with_parameter точно два параметъра ли могат да имат
@Светослав, блоковете, по дефиниция, могат да имат колкото си искат параметри. Но метода, който ги вика, трябва да им подава два.
parser.option('v', 'version', 'show version number') do |runner, value| runner[:version] = value end
Опциите винаги ли се задават по този начин, или е възможно първите 2 аргумента да са в разменен ред
parser.option('version', 'v', 'show version number')
@Иван, няма да са разменени. Кое в условието те навежда на този въпрос?
Възможно ли е да имаме
option
иoption_with_parameter
с еднакво име (кратък или дълъг вариант)? Тоест ако направим следното:parser = CommandParser.new('rspec') parser.option('v', 'version', 'show version number') do |runner, value| runner[:version] = value end parser.option_with_parameter('v', 'version', 'do something else with version') do |runner, value| #something else end
Трябва ли да се очаква
parser.parse(runner, ['--version'])
иparser.parse(runner, ['--version=larodi'])
да работят по различен начин?@Виктор, няма да има такива тестове. Също така няма да тестваме за случей в които една опция с или без параметър е дефинирана 2 пъти.
Конструкцията на нашата команда всъщност от кое се задава, от методите
#argument
,#option
и#option_with_parameter
или#parse
взема стойности отargv
масива и ги подава катоvalue
на блоковете в трите метода;parse
чете вече подадени аргументи и опции или ги генерира? Може би по-глобално въпросът ми е свързан с това как се генерира цялостната команда, защото по начало тя има само име и какво е точно взаимодействието между parse и другите методи. И последен, може би малко глупав въпрос, но каква е семантиката на блока{ |_, _| }
, подаван в тестовете?@Дарин, според мен, метода
#parse
просто се грижи за това да разбере дали нещата от масива са аргумент/опция или опция с аргмумент. Другите методи служат за генериране на документацията и изпълняване на блоковете, за да се пълни обектаcommand_runner
. Що се отнася до семантиката на блока{ |_, _| }
, в тестовете го подават защото се очаква блок, а аргументите на блока(_,_)
са просто placeholder-и, т.е. няма да се използват.parser = CommandParser.new('rspec') parser.argument('FILE') do |runner, value| runner[:file] = value end parser.argument('FILE') do |runner, value| runner[:file2] = value end command_runner = {} parser.parse(command_runner, ['spec.rb']) parser.parse(command_runner, ['spec2.rb'])
command_runner # =>
?и
parser = CommandParser.new('rspec') parser.argument('FILE') do |runner, value| runner[:file] = value end parser.argument('FILE2') do |runner, value| runner[:file2] = value end command_runner = {} parser.parse(command_runner, ['spec.rb']) parser.parse(command_runner, ['spec2.rb'])
command_runner # =>
?@Христо имената на аргументите имат значение само за генериране на документацията от
#help
. И 2та ти примера са невалидни защото викаш#parse
сargv
аргумент само с по един елемент докато си направил 2#argument
извиквания. Тези случей са невалидни.argv
винаги ще има точно толкова аргумента в себе си колкото и са извикванията на#argument
преди това.
Трябва да сте влезли в системата, за да може да отговаряте на теми.