Решение на Седма задача - ретроспекция от Цветан Христов

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

Към профила на Цветан Христов

Резултати

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

Код

REPOSITORY = 'https://github.com/TsHristov/ruby-retrospective-2016'
# Двадесет неща, които научих.
# Общи:
#
# 1. Основно нещо, което научих в курса бе това да ценя и да се стремя към добре и ясно написано код:
# “Programs must be written for people to read, and only incidentally for machines to execute.”
#
# 2. Използването на проверка за тип в динамичен език като Руби е безмислено,
# поради това подходящата употреба на 'Duck typing' е за предпочитане.
#
# 3. Регулярните изрази са много мощен инструмент. Употребата им обаче следва да бъде ограничена до решаване на подпроблеми чрез
# тях, а не до решаване на целия проблем посредством регулярен израз.
#
# 4. Метапрограмирането е необходимото зло в някои частни случаи. В общия случай има и по-подходящи методи за решаването на даден проблем.
#
# 5. Писането на тестове е от изключително голямо значение за продуктовия софтуер. На пръв поглед отнема време, но всъщност спестява
# много главоболия и изгубено време. 'Code coverage' e индикатор за функционалността на кода, но не е единствения такъв.
#
# 6. Оцених възможноста да се пишат DSL-и чрез Руби (поради това че езика дава много свобода).
# Останах още по-изненадан, когато осъзнах че всъщност Ruby on Rails e един гигантски DSL !
#
# За Руби:
#
# 7. Инстанционните променливи на класа и инстанционните променливи на неговите обекти са две различни неща.
# Тъй като класовете също са обекти (от тип Class), а инстанциите на класа отделни от него обекти, то те нямат споделени променливи.
# Изключение правят класовите променливи, които са видими и от класа и от неговите инстанции (включително от неговите наследници).
#
# 8. Не е нужно, навсякъде експлицитно да се слага 'self',
# self-а се определя спрямо обекта върху който се изпълнява метода.
#
# 9. Всяка една функция, всъщност представлява метод, тъй като винаги има текущ клас, в който този метод е дефиниран.
#
# 10. 'class', 'module' и 'def' представляват scope-gates, като по-този начин задават поле на видимост на променливите в тяхното тяло.
#
# 11. Модулите в Руби представляват много удобна функционалност на езика - 'mixins'. Чрез тях може да изнесем част от логиката на класа, която няма място нито в него,
# нито в родителя му. С 'extend' можем да включим методите на модул като класови методи на класа, а с 'include' като инстанционни.
# Също така модулите позволяват създаването на 'namespace'-и, като по този начин предовратяват евентуални колизии в именуването.
#
# 12. Един клас винаги може да бъде "отворен" (monkey-patch-нат), като така можем да разширим/променим неговата функционалност. Не винаги обаче е добра идея,
# тъй като бъдещи клиенти на класа могат да получат неочаквано поведение в следствие на нашата промяна.
#
# 13. Всеки метод в Руби може да приеме блок(анонимна функция), който може да бъде извикан чрез 'yeild' в тялото на метода.
#
# 14. Чрез attr_accessor, attr_reader, attr_writer позволяваме инстанционните променливи на класа да бъдат видими извън него. 'private' методи на класа не могат да бъдат
# викани чрез явен получател.
#
# 15. Всеки клас в Руби наследява от Object. Съществува понятие като 'ancestor_chain', който дефинира и реда на търсенето на методи, ако метод не бъде
# открит в текущия клас, то той се търси в миксирания модул, ако и там не бъде открит се търси в родителя на класа, ако не бъде открит след краен брой
# пъти прилагане на схемата за търсене се вика 'method_missing'.
#
# 16. Дефиницията на клас в Руби създава константа. Класът Object всъщност представлява главната отправна точка при търсенето на константи в Руби.
# Тъй като той има хеш-таблица с константите дефинирани в класа, които от своя страна имат свои дефинирани такива, търсенето на константи се реализира като
# последователно се претърсват тези вложени една в друга таблици.
#
# 17. Всички инстанционни методи в Руби са nil по подразбиране, функциите връщат nil по-подразбиране. Методите могат да връщат повече от една стойност, тогава
# при извикването на тази функцията, стойностите могат да се вземат посредством така наречения 'unpacking'.
# Може да имаме именовани аргументи при дефиницията на функция, което прави нейната употреба по лесна. Също така чрез '*arg' в израза:
# 'def some_function(*arg) end', можем да вземем списък от подадените аргументи на функцията.
#
# 18. Singleton class/“Собствен клас” в Руби, представлява възможността да се дефинира метод върху конкретен обект, по този начин
# правейки отделен клас за обекта съдържащ уникални методи за този обект.
#
# 19. 'RSpec' e Behaviour-Driven-Development тест библиотека за Руби, която представлява DSL написан на Руби. Чрез 'context', може логически да отделим
# конкретния случай, който тестваме, а чрез 'describe' да опишем какво тестваме. 'before' позволява задаването на състояние преди изпълняването на
# всеки test-case, 'let' от своя страна позволява да изнесем създаването на често повтарящ се обект извън групата. Важно е Unit-Test-овете да минават бързо,
# и да не "замърсяват околната среда".
# Хубаво е всеки един test-case да проверява за едно условие, тъй като това позволява по-добра локализациия на бъгове.
#
# 20. Научих, че искам да се занимавам с Руби, тъй като ми дава много свобода, има богат набор от библиотеки, удобен е за работа и преди всичко
# има много силно застъпено влияние на общността около него!
#
# Още:
# + разбрах какво представляват регулярните изрази, как се ползват и кога е уместно да се ползват.
# + разбрах що е то процес и нишка.
# + разбрах важността от това да се пишат тестове и четим код.

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

From https://github.com/fmi/ruby-retrospective-2016
 * branch            master     -> FETCH_HEAD
HEAD is now at a22cf37 Set rubocop version to 0.46.0 to fix obsolete cop errors
Cloning into 'submission'...
HEAD is now at cc52b40 Implement ArrayStore, HashStore, find_by methods for attributes
From /tmp/ruby-retrospective-2016/checker
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> upstream/master

Changes URL:
https://github.com/TsHristov/ruby-retrospective-2016/compare/1f710b00c26...cc52b40dd5e

'tasks/1/solution.rb' -> '/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb'
'tasks/2/solution.rb' -> '/tmp/ruby-retrospective-2016/checker/tasks/2/solution.rb'
'tasks/3/solution.rb' -> '/tmp/ruby-retrospective-2016/checker/tasks/3/solution.rb'
'tasks/4/solution.rb' -> '/tmp/ruby-retrospective-2016/checker/tasks/4/solution.rb'
'tasks/5/solution.rb' -> '/tmp/ruby-retrospective-2016/checker/tasks/5/solution.rb'
Inspecting 1 file
.

1 file inspected, no offenses detected
/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb:21: warning: key :water is duplicated and overwritten on line 26
/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb:22: warning: key :ethanol is duplicated and overwritten on line 27
/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb:23: warning: key :gold is duplicated and overwritten on line 28
/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb:24: warning: key :silver is duplicated and overwritten on line 29
/tmp/ruby-retrospective-2016/checker/tasks/1/solution.rb:25: warning: key :copper is duplicated and overwritten on line 30
.................

Finished in 0.00782 seconds
17 examples, 0 failures
Inspecting 1 file
.

1 file inspected, no offenses detected
...............

Finished in 0.00521 seconds
15 examples, 0 failures
Inspecting 1 file
.

1 file inspected, no offenses detected

...............

Finished in 0.00837 seconds
15 examples, 0 failures
Inspecting 1 file
.

1 file inspected, no offenses detected
....................

Finished in 19.42 seconds
20 examples, 0 failures
Inspecting 1 file
.

1 file inspected, no offenses detected
.........................

Finished in 0.01896 seconds
25 examples, 0 failures
.

Finished in 0.00168 seconds
1 example, 0 failures

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

Цветан обнови решението на 15.01.2017 23:07 (преди почти 8 години)

+REPOSITORY = 'https://github.com/TsHristov/ruby-retrospective-2016'
+
+# Двадесет неща, които научих.
+# Общи:
+#
+# 1. Основно нещо, което научих в курса бе това да ценя и да се стремя към добре и ясно написано код:
+# “Programs must be written for people to read, and only incidentally for machines to execute.”
+#
+# 2. Използването на проверка за тип в динамичен език като Руби е безмислено,
+# поради това подходящата употреба на 'Duck typing' е за предпочитане.
+#
+# 3. Регулярните изрази са много мощен инструмент. Употребата им обаче следва да бъде ограничена до решаване на подпроблеми чрез
+# тях, а не до решаване на целия проблем посредством регулярен израз.
+#
+# 4. Метапрограмирането е необходимото зло в някои частни случаи. В общия случай има и по-подходящи методи за решаването на даден проблем.
+#
+# 5. Писането на тестове е от изключително голямо значение за продуктовия софтуер. На пръв поглед отнема време, но всъщност спестява
+# много главоболия и изгубено време. 'Code coverage' e индикатор за функционалността на кода, но не е единствения такъв.
+#
+# 6. Оцених възможноста да се пишат DSL-и чрез Руби (поради това че езика дава много свобода).
+# Останах още по-изненадан, когато осъзнах че всъщност Ruby on Rails e един гигантски DSL !
+#
+# За Руби:
+#
+# 7. Инстанционните променливи на класа и инстанционните променливи на неговите обекти са две различни неща.
+# Тъй като класовете също са обекти (от тип Class), а инстанциите на класа отделни от него обекти, то те нямат споделени променливи.
+# Изключение правят класовите променливи, които са видими и от класа и от неговите инстанции (включително от неговите наследници).
+#
+# 8. Не е нужно, навсякъде експлицитно да се слага 'self',
+# self-а се определя спрямо обекта върху който се изпълнява метода.
+#
+# 9. Всяка една функция, всъщност представлява метод, тъй като винаги има текущ клас, в който този метод е дефиниран.
+#
+# 10. 'class', 'module' и 'def' представляват scope-gates, като по-този начин задават поле на видимост на променливите в тяхното тяло.
+#
+# 11. Модулите в Руби представляват много удобна функционалност на езика - 'mixins'. Чрез тях може да изнесем част от логиката на класа, която няма място нито в него,
+# нито в родителя му. С 'extend' можем да включим методите на модул като класови методи на класа, а с 'include' като инстанционни.
+# Също така модулите позволяват създаването на 'namespace'-и, като по този начин предовратяват евентуални колизии в именуването.
+#
+# 12. Един клас винаги може да бъде "отворен" (monkey-patch-нат), като така можем да разширим/променим неговата функционалност. Не винаги обаче е добра идея,
+# тъй като бъдещи клиенти на класа могат да получат неочаквано поведение в следствие на нашата промяна.
+#
+# 13. Всеки метод в Руби може да приеме блок(анонимна функция), който може да бъде извикан чрез 'yeild' в тялото на метода.
+#
+# 14. Чрез attr_accessor, attr_reader, attr_writer позволяваме инстанционните променливи на класа да бъдат видими извън него. 'private' методи на класа не могат да бъдат
+# викани чрез явен получател.
+#
+# 15. Всеки клас в Руби наследява от Object. Съществува понятие като 'ancestor_chain', който дефинира и реда на търсенето на методи, ако метод не бъде
+# открит в текущия клас, то той се търси в миксирания модул, ако и там не бъде открит се търси в родителя на класа, ако не бъде открит след краен брой
+# пъти прилагане на схемата за търсене се вика 'method_missing'.
+#
+# 16. Дефиницията на клас в Руби създава константа. Класът Object всъщност представлява главната отправна точка при търсенето на константи в Руби.
+# Тъй като той има хеш-таблица с константите дефинирани в класа, които от своя страна имат свои дефинирани такива, търсенето на константи се реализира като
+# последователно се претърсват тези вложени една в друга таблици.
+#
+# 17. Всички инстанционни методи в Руби са nil по подразбиране, функциите връщат nil по-подразбиране. Методите могат да връщат повече от една стойност, тогава
+# при извикването на тази функцията, стойностите могат да се вземат посредством така наречения 'unpacking'.
+# Може да имаме именовани аргументи при дефиницията на функция, което прави нейната употреба по лесна. Също така чрез '*arg' в израза:
+# 'def some_function(*arg) end', можем да вземем списък от подадените аргументи на функцията.
+#
+# 18. Singleton class/“Собствен клас” в Руби, представлява възможността да се дефинира метод върху конкретен обект, по този начин
+# правейки отделен клас за обекта съдържащ уникални методи за този обект.
+#
+# 19. 'RSpec' e Behaviour-Driven-Development тест библиотека за Руби, която представлява DSL написан на Руби. Чрез 'context', може логически да отделим
+# конкретния случай, който тестваме, а чрез 'describe' да опишем какво тестваме. 'before' позволява задаването на състояние преди изпълняването на
+# всеки test-case, 'let' от своя страна позволява да изнесем създаването на често повтарящ се обект извън групата. Важно е Unit-Test-овете да минават бързо,
+# и да не "замърсяват околната среда".
+# Хубаво е всеки един test-case да проверява за едно условие, тъй като това позволява по-добра локализациия на бъгове.
+#
+# 20. Научих, че искам да се занимавам с Руби, тъй като ми дава много свобода, има богат набор от библиотеки, удобен е за работа и преди всичко
+# има много силно застъпено влияние на общността около него!
+#
+# Още:
+# + разбрах какво представляват регулярните изрази, как се ползват и кога е уместно да се ползват.
+# + разбрах що е то процес и нишка.
+# + разбрах важността от това да се пишат тестове и четим код.