Георги обнови решението на 21.01.2014 22:54 (преди почти 11 години)
+REPOSITORY = 'https://github.com/gshopov/ruby-retrospective-3'
+
+# 1. На почти всичките ми решения skeptic се оплакваше за думи, които не са
+# английски. Това ме накара да си поиграя с именуването и да открия някои
+# доста глупави имена, които преди съм счел за удачни.
+
+# 2. При chain-ване на итератори, например each_with_index.each_with_object([]),
+# мога да получа стойността на елемента, индекса и списъка като отделни
+# променливи в блока. Тоест не трябва да се прави така:
+# { |item_index_tuple, list| ... }, продуцирайки глупави имена, а така
+# { |item, index, list| ... }. По този начин избягвам и глупости от рода на
+# item_index_tuple[0], item_index_tuple[1].
+
+# 3. Многократно пренаписвах итерации със select, map, reduce и т.н. вместо
+# each_with_object. Така кода стана по-сбит и по-експресивен, защото не
+# трябва да се проследява какво точно влиза в съответния обект и кое не.
+
+# 4. Припомних си какво каза веднъж Петко Борджуков: "по идиоматично за ruby е
+# използването на upto вместо на range-ове", и го приложих.
+
+# 5. Научих за Integer#remainder, Integer#zero?, Integer#nonzero? и ги
+# използвах, защото определено подобряват експресивността и четимостта -
+# получават се изрази на почти правилен английски.
+
+# 6. Според препоръка на style guide-а е по-добре да приемаме блока като
+# експлицитен аргумент, за да предотвратим ситуация, в която блока предава
+# аргументите си на друг блок.
+
+# 7. Може да подаваме символи, които представляват име на метод, който да се
+# използва като подаден блок. Синтаксис: &<method_name_as_a_symbol>. Това
+# което става е, че се извиква to_proc на самия символ, за да получим Proc
+# обект, след което с & казваме, че това ще е блокът, с който е извикан
+# number методът.
+
+# 8. В първото домашно използвах препоръката на Пламен да се отделя с един
+# празен ред, спрямо останалия код, това, което връща метода.
+
+# 9. Изкорених още едно нещо от C++: string_number.ord - '0'.ord. Сега вече
+# използвам String#to_i. :)
+
+# 10. Едно от най-полезните неща, които предлагат hash-овете е стойности по
+# подразбиране и дори блок, който да се извика, ако ключът не се намери.
+# Основната промяна в тази насока е в първата задача.
+
+# 11. По-идиоматично и по е използването на drop и take вместо слайсове, когато
+# изкаме да отрежем в началото или края, особоно, когато това е само първия
+# или само последния елемент.
+
+# 12. Според ръководството по стил, структурата на един клас трябва да има
+# следната подредба: 1) extend и include, 2) константи, 3) attribute макрота,
+# 4) други макрота, 5) public class methods, 6) public instance methods,
+# 7) накрая protected и private методи.
+# Това не беше спазено във второто домашно.
+
+# 13. Не трябва да се дава достъп до вътрешни применливи, които са свързани с
+# имплементацията(във втора задача имах accessor за такава променлива).
+# Докато се опитвах да реша проблема, разбрах нуждата от protected в ruby,
+# защото имах нужда от непубличен getter, който да може да се извиква от
+# инстанция на този клас, подадена като аргумент на инстанционен метод.
+
+# 14. Харесах стила на Димитър да подравнява последователни редове около
+# assignment оператора и други. Приложих го почти навсякъде и четимостта
+# се подобри в пъти.
+
+# 15. Изцяло пренаписах Criteria класът от втора задача, използвайки блокове,
+# за да пазя самото условие, което трябва да е изпълнено, а не да строя
+# изрази, които впоследствие да оценявам. Определено кода стана по-кратък и
+# ясен и се отървах от някои ужасни имена на променливи. :)
+
+# 16. Във втора задача бях направил ненужно разделение на два класа TodoList и
+# TaskList, като TodoList служеше единствено за парсване на текст и
+# създаване на TaskList инстанция. Първо, имената и на двата класа са много
+# близки по значение, аз поне ги тълкувам по един и същи начин. Второ, няма
+# логика да не върна инстанция на TodoList, а на TaskList, защото тогава
+# каква всъщност става ролята на TodoList?(не е ясно)
+
+# 17. Многократно е повтаряно и натяквано с домашни и предизвикателства, че
+# monkey-patch-ването не е препоръчително и трябва да се избягва, колкото
+# се може повече. Въпреки това в две от решенията си бях направил точно
+# обратното :). Премахнах monkey-patch-ове на TrueClass, FalseClass и Matrix,
+# въпреки че специално матрицата си търсеше боя - нямаше []= метод.
+
+# 18. Във втора задача изцяло откачих парсването на текста от TodoList и
+# по-важното от Task. Направих отделен клас, който да се грижи за това.
+# Добра практика е да има един отговорник за всяко действие, защото така
+# по-лесно се контролира комуникацията между класовете. Така както аз го
+# бях направил имах логика за парсване на текст в два отделни класа, които
+# дори не трябва да знаят, че има нещо наречено "парсване".
+
+# 19. Мега хитринка: ако класът ни имплементира Enumerable(дефинирали сме си
+# each), е ясно, че може да използваме всичко дефинирано в Enumerable. Това,
+# което е не толкова ясно е, че length метода е скрит под името count.
+# Поуката е по-често да се преглежда документацията на стандартната
+# библиотека и core, защото ако не друго то в ruby има много синоними и
+# в случая нама как, мислейки си за length, да ни дойде изведнъж count.
+
+# 20. Излючително полезно е да се използват вече дефинирани методи. Скъсява се
+# кода, избягва се повторение и понякога, както е в моя случай, кода става
+# по-ясен и изчистен. В решението ми на втора задача мога да използвам
+# вече дефинирания метод tasks_completed и новооткрития count, за да
+# изчистя метода completed?.
+
+# 21. Нещо, което бях забравил е, че не е удачно да се използват матрици или
+# двумерни масиви за представянето на така наречените sparse matrix -
+# матрици, в които повечето елементи са "празни"(дефинира се в контекста на
+# проблема). В тези случаи е по-добре да се използват множества и дори
+# hash-ове, в които да пазим само "запълнените" елементи. Въпреки това, не
+# бих казал, че конкретно 3-та задача е добър пример, защото можеше да са
+# такива примерите и тестовете, че цялото платно да е запълнено. Ситуация,
+# в която наистина ми се е налагало да използвам множества или hash-ове за
+# представяне на такива разредени матрици е при писане на Game of Life.
+
+# 22. Нещо, което наистина трябва да се запомни, защото подвежда хора, писали
+# на други езици, е, че "and" и "or" операторите имат равен приоритет, а
+# операторът && има по-висок приоритет от ||. Такава грешка, бях допуснал
+# в решението на трета задача.
+
+# 23. Научих, че в ruby няма такова нещо като private клас.
+
+# 24. Freeze-нах всички константи, които съм използвал в решенията, защото е
+# добра практика - добавя още една защита за невнимаващите. В ruby не може
+# да правим така: FOO = 1; FOO = 2;, но можем така: FOO = []; FOO << 1;.
+# Freeze ни пази точно от второто.
+
+# 25. "_" се използва за да обозначи параметри, които няма да използваме. Не го
+# бях използвал в четвърта задача, въпреки че го знаех. :/