Rubynovich
Rubynovich. Это прозвище дали первые студенты своему преподавателю по предмету «Программирование на языках высокого уровня». Для демонстрации высокоуровневых алгоритмов он использовал язык Ruby, что и послужило предпосылкой для появления такого прозвища.
Rubynovich преподает предмет «Программирование на языках высокого уровня» в МЭТТ с 2003 года. За это время он сумел сформировать собственную программу обучения и свое уникальное видение сути предмета.
Высокоуровневое программирование
правитьВот некоторые принципы программирования, которых должен придерживаться высокоуровневый программист:
- отсутствие переменных (чем меньше переменных, тем меньше ошибок);
- отсутствие циклов (все циклы должны быть заменены на итераторы);
- отстутствие условных конструкций if, case и т.д. (если они есть, то вы делаете, что-то не так);
- должны выполняться правила рефакторинга (код должен «хорошо пахнуть»).
Отсутствие переменных
правитьЕсли переменные отсутствуют, то что-то же использовать вместо них? Параметры методов/замыканий и константы. Это значит, что строки вида:
a = 0 a += 5
являются ошибочными, т.к. присутствует два присваивания значения одной и той же переменной. Скорее всего суммирование можно перенести на момент присваивания начального значения:
a = 5
Это выражение является более правильным с точки зрения высокоуровневого программирования. Давайте рассмотрим немного более сложный пример неправильного кода:
sum = 0 (1..5).each{ |i| sum += i } p sum
Как мы видим, внутри блока присутствует второе присваивание, что противоречит нашему принципу. Как от него избавиться? Использовать не .each, а специализированный метод .inject для суммирования/умножения/конкатенации:
p (1..5).inject( 0 ){ |sum,i| sum + i }
Как мы видим, нам не только удалось избавиться от двух присваиваний, но и превратить переменную в параметр. Кстати, решение задачи получилось «в одну строчку».
Отсутствие циклов
правитьЧем же так плохи циклы? Тем, что «зацикливаются» и заранее нельзя указать количество итераций, которые они выполнят. Эта неопределенность погубила не одно поколение программистов. Поэтому и была придумана концепция итераторов, т. е. циклических конструкций, количество итераций которых заранее известно. Пример цикла:
a = [1,2,3,4,5,6] i = 0 while i < a.size do puts a[i] i += 1 end
Как вы можете видеть, здесь не только использование цикла, но и двойного присваивания. С итератором эта программа будет выглядеть так:
[1,2,3,4,5,6].each{ |elem| puts elem }
Стоит заметить, что мы избавились не только от двойного присваивания и цикла, но и от переменной, которая превратилась в параметр блока итератора.
Отсутствие условных конструкций if, case и т.д.
правитьОказывается, что условные операторы вовсе не обязательны. Давайте рассмотрим несколько приемов, которые позволяют их избежать. Допустим у нас есть программа вида:
a, b = 5, 6 if a > b puts "a > b" elsif a == b puts "a == b" else puts "a < b" end
Казалось бы, все очевидно и по другому быть не может. Rubynovich же предлагает заменить результаты массивом вариантов:
["a == b","a > b","a < b"]
и использовать оператор <=> для получения индекса варианта. Решение для вышеуказанного примера будет выглядеть так:
a, b = 5, 6 puts ["a == b","a > b","a < b"][ a <=> b ]
Естественно, что пример был выбран искусственно, но сама по себе идея достаточно интересна. Кстати, как написать программу, которая выводит "a == b" или "a != b"?
Должны выполняться правила рефакторинга
правитьМартин Фаулер написал замечательную книгу "Рефакторинг". Что же такое этот рефакторинг? Рефакторинг — это процесс переработки программного кода с сохранением его функциональности. Делается это для того, чтобы стабильный код становился еще и изящным (лишенным конструктивных изъянов). Это необходимо для улучшения способности кода к безболезненной модификации. Многие программисты используют рефакторинг и как средство повышения профессионализма, и как повод получше разобраться в своем или чужом коде.
Вместо заключения
правитьВот так посмотришь на все программы, которые получаются в результате преобразований и Rubynovich уже не кажется таким уж сумасшедшим.