Весьма мудрое на RSDN Основная мысль: большая часть новых парадигм и веяний в программировании -- изменяют структуру программы на "высоком" уровне (вводятся новые единицы структурирования и новые взаимодействия между ними), в то время как на уровне отдельных методов все те же "операторы цикла"/"операторы ветвления" (ррррр, да, я школьный учитель информатики!!!111). Но в этой области вполне возможен прогресс, и он уже идет -- силами функционального программирования (pattern-matching, tuples, local functions).
Это очень сильно коррелирует с моим "чувством прекрасного" кода (в сегодняшнем понимании, через два года после перехода C++ => Ruby как основной язык). Оно (это "чувство прекрасного") действительно формулируется как "условный оператор и оператор цикла в коде -- признак некрасивого и неоптимального решения задачи".
Потому што вместо цикла почти всегда "более явно выразит намерения" map/reduce-образный код:
some_array = some_other_array.
map{|item| some_transormation(item)}.
reject{|item| some_condition(item)}
# и т.п.
С условиями немного сложнее, потому что "настоящего" pattern-matching в Ruby нету -- зато есть очень мощный case:
case my_string
when Array : blah-blah
when nil : blah
when /f.uc.*/,
/s.u.*/ : blah
when 'some' : blah
end
#или даже так:
case
when x == 0 : blah
when y > 0 : blah
...
end
На мой личный извращенный вкус этот код лучше чем колбаса if'ов своей регулярностью. Назовем такой код in-place полиморфизмом: для коротких кусков кода построение логики таким образом зачастую оказывается куда очевиднее (и, кстати, мощнее) чем множество полиморфных методов или иерархия объектов.
Интересно, что в "принципах ООП" есть почти явный запрет на case (см., например, в
Bad Code Smells: "The Object-Orientation Abusers: - Switch Statements"). На мой вкус, это доказывает только одно: за глобальные принципы часто принимают нечто, исходящее из свойств конкретного языка Например:
* из школьной программы: "ученики должны точно понимать разницу между процедурой и функцией";
* голова моя уже забыла детали, но вроде как было у плюсовиков именное "правило хорошего тона" -- не раздувать интерфейс класса, составляя "API класса" по мере необходимости из "свободных" методов. Тем временем, открытые классы Ruby (и, насколько я понимаю, extension methods в C#) порождают традицию добавлять релевантное API прямо в класс (например, в моем проекте есть файл ui_formatters.rb, добавляющий методы, позволяющие дальше в коде писать 25.30.as_usd или Time.now.as_ru_date -- они превращают дроби и даты в именно такие строки, как надо моему конкретному проекту).
И, напоследок, несколько спорный тезис: идеальный метод -- это ровно 1 expression, выполняющий заданное действие или дающий ответ на заданный вопрос. Соответственно, "идеальный" для методов язык должен сделать возможной реализацию этого тезиса. Типа того.