Решение на Пета задача от Мартина Радева

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

Към профила на Мартина Радева

Резултати

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

Код

REPOSITORY = 'https://github.com/martaradeva/ruby-retrospective-4'
# 20 неща, които научих за Ruby (и не само)
# За Git
# 1. Kак да разрешавам merge conflicts.
# 2. Как да sync-вам fork през command line git
# Задача 2.
# 3. За да мога да chain-вам методи (метод сам на себе си), трябва методът ми да връща self.
# 4. Наследяването на класове прави методите на родителя достъпни в детето.
# Методите | и & дефинирам само във Filter, като SignFilter и TypeFilter (ги) наследяват от него.
# 5. С context 'context_name' {#block_of_tests} в RSpec можем да разделяме различните тестове
# според вида на функционалността, която тестват. По-удобно подреждане на резултатите.
# Вероятно могат и да се настройват специфични за контекста условия.
# Задача 3.
# 6. Открих си грешка (?!) във file parse -> направила го бях да работи само за String. Сега работи за всички типове данни.
# 7. Когато се дефинира lambda с -> параметъра се изкарва пред скобите на блока. -> x, y { x + y }
# 8. String#delete! изтрива всичко, което match-не на параметъра, с който се извиква. от всяка част на стринга. Мутира съществуващия обект.
# 9. Hash#merge! добавя нов хеш към съществуващ. Презаписва повтарящите се ключове. Мутира съществуващия обект.
# 10. Методите, мутиращи съществуващия обект (merge! , delete! и т.н.)и затова би трябвало да се избягват.
# Тоест добре е да заменим конструкцията
# hash.merge! other_hash
# с тази
# hash = hash.merge other_hash
# Защото тя не променя оригиналния обект, към който биха могли да сочат и други променливи.
# 11. При извикване на класовите методи от контекста на самия клас името на класа може да се пропусне (self се подразбира)
# 12. Наличие на опционални аргументи (wildcard arguments) в метод става с
# def my_method (*args)
# args.length > 0 #true, ако са подадени, false ако не са
# args[0] #true ако са подадени, nil ако не са. Не е коректно в частния случай, в който се извика my_method(nil).
# args #true винаги, защото не е nil
# end
# 13. В дефинирането на метода може да се зададе стойност по подразбиране на keyword аргументите, която се взима,
# ако не се подадат аргументи при извикването на метода. По този начин не се хвърля грешка, ако не се подадат аргументи.
# def my_method (:arg1="", :arg2=nil)
# @arg1 = arg1
# @arg2 = arg2
# end
# 14. размисли по ООП - отделянето на някаква логика в отделен клас (модул, метод) се случва
# (1).когато тази логика видимо се повтаря на няколко места, или
# (2).когато обменът на информация с останалата част от класа(модула) става през относително ясен интерфейс.
# 15. Подаване на блок от код на модул с yield.
# 16. Интерполацията на String е добър и лаконичен начин да сериализираме съдържанието на променливи, защото едновременно
# им вика to_s и можем директно да ги поставим на мястото им в string-a.
# 17. За дефинираните от мен класове е добре да си дефинирам и метод inspect или to_s, който да връща съдържанието на полето / полетата,
# които има смисъл да се инспектират.
# (EDIT - "още по-удобно за debug е p (работи горе-долу така: def p(obj) { puts(obj.inspect); obj }).")
# Задача 4.
# 18. Добрата архитектура на една задача е ОК да се търси итеративно.
# Работещото решение може да се рафинира краен брой пъти, като се подобрява структурата на кода
# чрез обособяване на повтарящата се логика в отделни елементи,
# преосмисляне на принадлежността на отделните части от логиката към най-подходящия клас или модул
# и преработване на взаимовръзките между тях, за да са максимално кратки и ясни.
# 19. super извиква същия метод на родителския клас.
# 20. String#ljust(length, 'pattern') допълва инстанция на string до зададена дължина length с някакъв подаден pattern.

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

Мартина обнови решението на 19.01.2015 16:36 (преди почти 10 години)

+REPOSITORY = 'https://github.com/martaradeva/ruby-retrospective-4'
+
+# 20 неща, които научих за Ruby (и не само)
+
+# За Git
+
+# 1. Kак да разрешавам merge conflicts.
+# 2. Как да sync-вам fork през command line git
+
+# Задача 2.
+
+# 3. За да мога да chain-вам методи (метод сам на себе си), трябва методът ми да връща self.
+# 4. Наследяването на класове прави методите на родителя достъпни в детето. Методите | и & дефинирам само във Filter, като SignFilter и TypeFilter (ги) наследяват от него.
+# 5. С context 'context_name' {#block_of_tests} в RSpec можем да разделяме различните тестове според вида на функционалността, която тестват. По-удобно подреждане на резултатите. Вероятно могат и да се настройват специфични за контекста условия.
+
+# Задача 3.
+
+# 6. Открих си грешка (?) във file parse -> направила го бях да работи само за String. Сега работи за всички типове данни.
+# 7. Когато се дефинира lambda с -> параметъра се изкарва пред скобите на блока в кръгли скоби. ()
+# 8. String#delete! изтрива всичко, което match-не на параметъра, с който се извиква. от всяка част на стринга.
+# 9. Hash#merge! е начинът да добавиш нов хеш към съществуващ. Презаписва повтарящите се ключове.
+# 10. При извикване на класовите методи от контекста на самия клас името на класа може да се пропусне (self се подразбира)
+# 11. Наличие на опционални аргументи (wildcard arguments) в метод става с
+# def my_method (*args)
+# args.length > 0 #true, ако са подадени, false ако не са
+# args[0] #true ако са подадени, nil ако не са
+# args #true винаги, защото не е nil
+# end
+# 12. размисли по ООП - отделянето на някаква логика в отделен клас (модул, метод) се случва (1).когато тази логика видимо се повтаря на няколко места, или (2). когато се усетиш, че обменът на информация с останалата част от класа(модула) става през относително ясен интерфейс.
+
+# Задача 4.
+# 13. При извикването на класовите методи от контекста на самия клас self може да се пропусне и се викат направо с name_of_method(args) - т.е. с подразбиращ се получател.
+# 14. За дефинираните от мен класове е добре да си дефинирам и метод inspect или to_s, за да мога по-лесно да дебъгвам с puts.
+# 15. Добрата архитектура на една задача е ОК да се търси итеративно. Работещото решение може да се рафинира краен брой пъти, като се вдига нивото на абстракция и се подобрява структурата на кода.

Добри наблюдения! Малко бележки по тях:

  • По 7. - може и без скоби, както и при другите методи, т.е.: -> x { x * x } или ->(x) { x * x }
  • По 8. и 9. - тези две версии мутират обекта, над който са извикани; обикновено се предпочитат немутиращите версии, т.е. тези без ! в края.
  • По 11 - трябва да отбележа само, че args[0] може и да не се оцени на истина в случая на my_method(nil).
  • Точка 13 се повтаря с т. 10.
  • 14 - още по-удобно за debug е p (работи горе-долу така: def p(obj) { puts(obj.inspect); obj }).
  • 15 - не винаги по-високо ниво на абстракция е добра идея. Абстракциите внасят усложнение.

Мартина обнови решението на 21.01.2015 16:12 (преди почти 10 години)

REPOSITORY = 'https://github.com/martaradeva/ruby-retrospective-4'
# 20 неща, които научих за Ruby (и не само)
-# За Git
+# За Git
# 1. Kак да разрешавам merge conflicts.
# 2. Как да sync-вам fork през command line git
-# Задача 2.
+# Задача 2.
# 3. За да мога да chain-вам методи (метод сам на себе си), трябва методът ми да връща self.
-# 4. Наследяването на класове прави методите на родителя достъпни в детето. Методите | и & дефинирам само във Filter, като SignFilter и TypeFilter (ги) наследяват от него.
-# 5. С context 'context_name' {#block_of_tests} в RSpec можем да разделяме различните тестове според вида на функционалността, която тестват. По-удобно подреждане на резултатите. Вероятно могат и да се настройват специфични за контекста условия.
+# 4. Наследяването на класове прави методите на родителя достъпни в детето.
+# Методите | и & дефинирам само във Filter, като SignFilter и TypeFilter (ги) наследяват от него.
+# 5. С context 'context_name' {#block_of_tests} в RSpec можем да разделяме различните тестове
+# според вида на функционалността, която тестват. По-удобно подреждане на резултатите.
+# Вероятно могат и да се настройват специфични за контекста условия.
-# Задача 3.
+# Задача 3.
-# 6. Открих си грешка (?) във file parse -> направила го бях да работи само за String. Сега работи за всички типове данни.
-# 7. Когато се дефинира lambda с -> параметъра се изкарва пред скобите на блока в кръгли скоби. ()
-# 8. String#delete! изтрива всичко, което match-не на параметъра, с който се извиква. от всяка част на стринга.
-# 9. Hash#merge! е начинът да добавиш нов хеш към съществуващ. Презаписва повтарящите се ключове.
-# 10. При извикване на класовите методи от контекста на самия клас името на класа може да се пропусне (self се подразбира)
-# 11. Наличие на опционални аргументи (wildcard arguments) в метод става с
-# def my_method (*args)
-# args.length > 0 #true, ако са подадени, false ако не са
-# args[0] #true ако са подадени, nil ако не са
-# args #true винаги, защото не е nil
-# end
-# 12. размисли по ООП - отделянето на някаква логика в отделен клас (модул, метод) се случва (1).когато тази логика видимо се повтаря на няколко места, или (2). когато се усетиш, че обменът на информация с останалата част от класа(модула) става през относително ясен интерфейс.
+# 6. Открих си грешка (?!) във file parse -> направила го бях да работи само за String. Сега работи за всички типове данни.
+# 7. Когато се дефинира lambda с -> параметъра се изкарва пред скобите на блока. -> x, y { x + y }
+# 8. String#delete! изтрива всичко, което match-не на параметъра, с който се извиква. от всяка част на стринга. Мутира съществуващия обект.
+# 9. Hash#merge! добавя нов хеш към съществуващ. Презаписва повтарящите се ключове. Мутира съществуващия обект.
+# 10. Методите, мутиращи съществуващия обект (merge! , delete! и т.н.)и затова би трябвало да се избягват.
+# Тоест добре е да заменим конструкцията
+# hash.merge! other_hash
+# с тази
+# hash = hash.merge other_hash
+# Защото тя не променя оригиналния обект, към който биха могли да сочат и други променливи.
-# Задача 4.
-# 13. При извикването на класовите методи от контекста на самия клас self може да се пропусне и се викат направо с name_of_method(args) - т.е. с подразбиращ се получател.
+# 11. При извикване на класовите методи от контекста на самия клас името на класа може да се пропусне (self се подразбира)
-# 14. За дефинираните от мен класове е добре да си дефинирам и метод inspect или to_s, за да мога по-лесно да дебъгвам с puts.
+# 12. Наличие на опционални аргументи (wildcard arguments) в метод става с
-# 15. Добрата архитектура на една задача е ОК да се търси итеративно. Работещото решение може да се рафинира краен брой пъти, като се вдига нивото на абстракция и се подобрява структурата на кода.
+# def my_method (*args)
+# args.length > 0 #true, ако са подадени, false ако не са
+# args[0] #true ако са подадени, nil ако не са. Не е коректно в частния случай, в който се извика my_method(nil).
+# args #true винаги, защото не е nil
+# end
+# 13. В дефинирането на метода може да се зададе стойност по подразбиране на keyword аргументите, която се взима,
+# ако не се подадат аргументи при извикването на метода. По този начин не се хвърля грешка, ако не се подадат аргументи.
+# def my_method (:arg1="", :arg2=nil)
+# @arg1 = arg1
+# @arg2 = arg2
+# end
+
+# 14. размисли по ООП - отделянето на някаква логика в отделен клас (модул, метод) се случва
+# (1).когато тази логика видимо се повтаря на няколко места, или
+# (2).когато обменът на информация с останалата част от класа(модула) става през относително ясен интерфейс.
+# 15. Подаване на блок от код на модул с yield.
+# 16. Интерполацията на String е добър и лаконичен начин да сериализираме съдържанието на променливи, защото едновременно
+# им вика to_s и можем директно да ги поставим на мястото им в string-a.
+# 17. За дефинираните от мен класове е добре да си дефинирам и метод inspect или to_s, който да връща съдържанието на полето / полетата,
+# които има смисъл да се инспектират.
+# (EDIT - "още по-удобно за debug е p (работи горе-долу така: def p(obj) { puts(obj.inspect); obj }).")
+
+# Задача 4.
+
+# 18. Добрата архитектура на една задача е ОК да се търси итеративно.
+# Работещото решение може да се рафинира краен брой пъти, като се подобрява структурата на кода
+# чрез обособяване на повтарящата се логика в отделни елементи,
+# преосмисляне на принадлежността на отделните части от логиката към най-подходящия клас или модул
+# и преработване на взаимовръзките между тях, за да са максимално кратки и ясни.
+# 19. super извиква същия метод на родителския клас.
+# 20. String#ljust(length, 'pattern') допълва инстанция на string до зададена дължина length с някакъв подаден pattern.