Мартина обнови решението на 25.01.2016 01:19 (преди над 9 години)
+REPOSITORY = 'https://github.com/misosupu/ruby-retrospective-2015-1'
+
+# Какво научих от Ruby Retrospective, част 1:
+#
+# 1. Хешовете в ruby имат "опростен" запис при работа с ключове, които са от тип symbol
+# вместо да се напише така:
+# EXCHANGE_RATE = { :usd => 1.7408, :eur => 1.9557, :gbp => 2.6415, :bgn => 1 }
+# можем да напишем следното:
+# EXCHANGE_RATE = { usd: 1.7408, eur: 1.9557, gbp: 2.6415, bgn: 1 }
+#
+# 2. Насърчаване на използване на символи спрямо низове като ключове на хеш
+#
+# Взето от "Ruby Style guide": "Prefer symbols instead of strings as hash keys."
+#
+# 3. На какъв принцип работи spaceship operator-ът при сравняване на обекти:
+# a <=> b връща -1 ако a е преди b,
+# 0 ако са равни
+# или 1 ако a е след b
+#
+# 4. типове променливи в Ruby и конвенцията за именоването им:
+# $variable = константа
+# Variable = глобална (за namespace-a) променлива
+#
+# * Bonus: да не предполагам, че през първата седмица от семестъра няма да се дават домашни
+#
+# 5. Няма смисъл от допълнителни операции, документацията съществува, за да се чете, например:
+# new_snake.shift
+# new_snake
+#
+# може да се замени просто със snake.drop(1)
+#
+# 6. [Концептуално] Хубаво е смислово различните случаи да се разделят в отделни методи, по този начин се улеснява тестването (TDD), кодът става по-четим и рефакторирането - по-лесно.
+#
+# Например за функцията obstacle_ahead? очевидно имаме 2 случая:
+# 1) змията пресича "себе си"
+# или
+# 2) змията пресича "границата"
+#
+# Разделяйки тези 2 случая в отделни методи е подобрение, освен по горепосочените причини, а и че намалява branching factor-a на метода. Добре е методите да правят точно това, което е името им, а не хиляда други неща. Грозно и нефункционално е.
+#
+# 7. Премахване на безсмиленото усложняване на код
+# x.zip(y).reduce(:+) е overkill
+# Освен, че е по-бавно, прави кода ненужно по-сложен и трудно читаем.
+#
+# По-краткото невинаги е най-доброто - "Programs were made for people to read and occasionally for machines to execute."
+#
+# 8. Отново, от Ruby Style guide-а:
+# "The and and or keywords are banned. It's just not worth it. Always use && and || instead."
+# Навсякъде съм заменила използването на 'and' и 'or' с '&&' и '||'.
+#
+# 9. Разлика между използването на ".." и "..." при задаване на range:
+# a..b is like a <= x <= b, whereas a...b is like a <= x < b
+#
+# 10. "Prefer Guard Clauses over nested conditionals"
+# Например:
+# if number == 1 || number == 2
+# return true
+# end
+#
+# може да се запише и така:
+# return true if number == 1 || number == 2
+#
+# 11. Използването на "upto" вместо range понякога подобрява четимостта и прави кода по-елегантен, отколкото използването на range.
+#
+# 12. Разликата между Struct и OpenStruct e, че с OpenStruct може динамично да се задават атрибути на даден обект, докато при Struct всички атрибути се задават при дефинирането.
+#
+# [Концептуално] Използването на Struct подобрява четимостта на кода.
+#
+# 13. [Концептуално]
+#
+# Преименуване на всички методи, съдържащи is_something? на something?. Въпросителната накрая говори достатъчно красноречиво за целта на метода.
+#
+# 14. Използване на unless, вместо if not.
+#
+# 15. Няма смисъл от отделен клас RationalSequenceElement с функционалност само един метод - всичко това може да стане със Struct и private method
+#
+# 16. Извикване на методи със символи, например cards.select(&:queen?) вместо card.select {|card| card.queen?}
+# Този начин е по-чист, елегантен и четим.
+#
+# 17. [Концептуално] Хубаво е да се групират общите функционалности на няколко класа и или да има основен, който да се наследява (например WarDeck < GenerickDeck) или общите методи да се групират в отделен модул, които да се mixin-не в съответните класове.
+#
+# 18. Съкратен начин на Array#push е операторът '<<'
+#
+# Например, вместо [1, 2, 3].push(4) # => [1, 2, 3, 4]
+# можем да напишем [1, 2, 3] << 4
+#
+# 19. Доста от методите в Ruby имат синоними (например size, length и.т.н.), но има методи, при които използването на един от синонимите е силно непрепоръчително, поради неудачно/смущаващо име.
+#
+# Например Enumerable#reduce и Enumerable#inject.
+#
+# 20. Тъй като в Ruby всеки метод по default връща последно оценения израз, добра идея е да избягваме множество return-и в средата на метода, тъй като обезсмислят първоначалната идея. Функциите стават по-четими и се намалява вероятността за по-голям branching factor, ако избягваме прекаленото използване на return клаузи.
+#
+# Bonus:
+# 1. Научих, че Rational е синтактична захар за named tuple.
+# 2. Ruby не е Python - имената на методи не започват с underscore, нито с dunder - използват се *something* private, public, protected.
Не бих казал, че inject
е точно смущаващо име. Не е довело до основаването на наркомански култ or something. xd
Причините reduce
да се предпочита IMHO:
- По-ясно е. Да, във функционален контекст
inject
също може да значи само едно нещо, но все пакreduce
е по-недвусмислено. По същия начин е по-добре и отaccumulate
. - По-разпространен е в developer culture-a като цяло. Хората говорят за MapReduce, не за MapInject.
- Преди
each_with_object
е имало хора, които са използвалиreduce
за "идиоматиченreduce
" иinject
за това, за коетоeach_with_object
е предназначен. Сега като вече го има...