Аксения обнови решението на 14.11.2011 08:32 (преди около 13 години)
+REPOSITORY = 'https://github.com/fmi/ruby-homework.git'
+
+# homework# 1
+# - не се поощрява използването на експлицитен self - много ми е странно без него, но предполагам е въпрос на свикване
+
+# - когато при обхождане, обекта, който очакваш е от повече от един елемент е по-добре да подадеш на блока няколко параметъра, вместо да индексираш – получава се по-ясно, имаш параметри с описателно име вместо индекси (referens HW1#to_hash)
+
+# - използването на yield е cool - първо, че като викаш yield кодът изгелжда по-чист, второ, че така не е нужно да подаваш блок на ф-ията (referens HW1#index_by)
+
+# - each_cons - знаех си, че има такъв метод, но явно не съм търсила достатъчно
+
+# - Array#count - не знаех, че count е предефиниран за списъци
+
+# - излишният код е зло – продължавам да мисля твърде много за валидация на аргументи, което води до излишен код, което води до проблеми
+
+# homework# 2
+# - много, ама много, много лоша идея е ползването на “\” за line continuation :(
+
+# - мутиращите операции не са на почит - select!, reject!, uniq!... removed
+
+# - има страшно страннен метод за отсяване на дублираните елементи в списък - uniq
+
+# - как да извикваме private/protected методи с Object#send
+
+# - arr = [*arr] <=> Array(arr), но не се бях сетила за това; и първото ми допада повече
+# (в духа на Array(arr) разбрах, че има нещо като Hash[] <=> {} и е изключително, ама изключително грозно и подвеждащо и бррр)
+
+# - chomp('!') е в пъти по-подходящо от gsub(/\!/, ''), толкова по-добре изразява какво трябва да се направи
+# (същото е положението с tag.include? "!" и tag.end_with? '!')
+
+# - Hash#fetch или по-точно, че можеш да му дадеш опционален аргумент, който да бъде резултат, ако не бъде намерен ключ с посочената стойност
+
+# homework# 3
+# - изполването на модули е хубаво – отделянето на част от функционалността в модули е много удобно: обособява се една независима от останалия код част, която е лесно преизползваема
+
+# - Null Object Pattern – добавянето на клас, който обхваща случая на липса на даден атрибут (в случая promotion/coupon) е много удобно; изчиства се някой друг if, логиката продължава да върви гладко и не е нужо специална обработка при достигане на иначе липсващия атрибут
+
+# - ruby е доста умен, сеща се какво омам предвид дори да не съм особенно ясна – визирам “@” въпреки, че абсолютно и тотално съм забравила да ги слагам той се сеща какво съм имала предвид (изключвайки няколко места, където явно не е било ясно и имах нужда от експлиците self; друг е въпросът, че това не ме подсети, че греша някъде)
+
+# - Enumerable#detect – когато очакваме един обект след прилагане на някакво филтриращо условие е много по-добър избор от #select
+
+# - Kernel#sprintf – заслужава по-внимателно преглеждане, има адски много опции; въпреки, че ми е що годе познат, ме изненада флагът “-”, с който се добавят водещи “space”-ове; а също не знам защо държах да си пиша *sprintf* "format string", arg - явно наистина имам нужда от опресняване на този метод
+
+# - inject(0) { |sum, cart_item| sum += cart_item.price } vs map(&:price).inject(:+) - и 2то печели категорично, много по-елегантно е
+
+# - case-ът явно не е лош избор – първоначалната ми идея за определяне на вида на промоциите и купоните беше точно с case, но ми се стори грозно и го промених на hash[key].nil?, но така наистина стана грозно, а явно case не е лош избор в такива случаи :(
+
+# - ограниченията водят до интересни неща: в класа ShoppingCart имах няколко метода в повече. На пръв поглед имах няколко много лесни начина да се справя с това, но всички щяха да доведат до някакъв вид неконсистентност (да махна отделните методи за валидация, да махна едни методи, които не са належащи довеждайки до малко повторение). И така стигнах до решението да обединя методите за намиране на цените на продуктите, общата стойност на отстъпките и тази на купона в един метод и да съхранявам тези стойности в хеш. И мисля, че се полчи доста добре. Първо избегнах повторението, второ продължих да си правя валидацията по един и същи начин и кодът продължи да бъде ясен. Личното ми заключение, е че изпозлването на хеша, като вид наименовани параметри е доста удобно
+
+
+# General conclusions:
+# - стилови конвенции:
+# * има скоби при дефиниране на метод с поне един аргумент (това уж го знаех, но няколко пъти го сбърках)
+# * има разстояния около “=” при аргументите по подразбиране (това вече не го знаех)
+
+# - дизайнът е сложен – до сега съм получавала много ясни описания на домашните – да има този и този клас, всеки да има тези и тези методи. Сега е различно - сам трябва да измислиш какви класове да имаш, как да съхраняваш данните си, с какви методи да разполагш, как да си взаимодействат класовете. Лошите решения правят надграждането сложно, а редизайна - тежък :(
+
+
+# Лирично отклонение:
+# - unless
+# Опитвах се да ползвам повече unless и горе-долу се получи. Горе-долу, защото първата ми мисъл беше бла-бла-бла if not. Веднага щом го напишех се връщах и го поправях. И ми стана чудно, защо става така. Стигнах до заключението, че има общо с нашето двойно отрицание. Според моето малко допитване казваме: “Изгаси лампата, освен ако не ти трябва”, а не “Изгаси лампата, освен ако ти трябва” От там идва моето малко объркване и несигурност, когато трябва да заместя if not с unless. Като изклчим това, +1 за unless.