Выбрать главу

Каждый программист сегодня знает о принципе ортогональности (хотя лучше было бы назвать его принципом ортогональной полноты). Вообразим пару осей, по одной из которых откладываются языковые сущности, а по другой — множество атрибутов и возможностей. Когда мы говорим об ортогональности, то обычно имеем в виду, что пространство, определяемое этими осями, настолько «полно», насколько это логически возможно.

Одна из составных частей Пути Ruby — стремление к ортогональности. Массив в некоторых отношениях подобен хэшу, а потому и операции над ними должны быть похожи. До тех пор пока мы не вступаем в область, где эти сущности начинают отличаться друг от друга.

Мац говорит, что «естественность» важнее ортогональности. Но чтобы понять, что естественно, а что нет, надо долго думать и писать программы.

Ruby стремится быть дружелюбным к программисту. Например, у многих методов есть синонимы; оба метода size и length возвращают число элементов в массиве. Два разных написания слова — indexes и indices — относятся к имени одного и того же метода. Некоторые называют это досадным недоразумением, но я склонен считать такую избыточность хорошим дизайном.

Ruby стремится к последовательности и единообразию. В этом нет ничего мистического: во всех жизненных ситуациях мы жаждем регулярности и размеренности. Сложнее научиться понимать, когда этот принцип следует нарушить.

Например, в Ruby принято добавлять вопросительный знак (?) в конец имени метода, ведущего себя как предикат. Это хорошо и удобно, программа становится яснее, а в пространстве имен легче ориентироваться. Но менее последовательным является аналогичное употребление восклицательного знака для обозначения потенциально «деструктивных» или «опасных» методов (в том смысле, что они модифицируют внутреннее состояние вызывающего объекта). Непоследовательность состоит в том, что не все деструктивные методы помечаются таким образом. Нужно ли восстановить справедливость?

Нет, на самом деле не нужно. Некоторые методы по сути своей изменяют состояние (например, методы replace и concat класса Array). Одни являются «методами установки», которые допускают присваивание атрибуту класса; ясно, что не следует добавлять восклицательный знак к имени атрибута или к знаку равенства. Другие в каком-то смысле изменяют состояние объекта, например read, но это происходит так часто, что нет смысла особо отмечать данный факт. Если бы имя каждого деструктивного метода заканчивалось символом !, то программа превратилась бы в рекламную брошюру фирмы, занимающейся многоуровневым маркетингом.

Вы замечаете действие разнонаправленных сил, тенденцию нарушать все правила? Тогда позвольте мне сформулировать второй закон Фултона: «У каждого правила есть исключения, кроме второго закона Фултона». (Доля шутки тут есть, но небольшая.)

В Ruby мы видим не «педантичную непротиворечивость», а строгое следование набору простых правил. Может быть, отчасти Путь Ruby состоит в том, что его подход не является закостенелым и неподвижным. Мац как-то сказал, что при проектировании языка нужно «следовать велениям своего сердца». И еще один аспект философии Ruby: «Не бойтесь изменений во время выполнения, не бойтесь быть динамичными». Мир динамичен, так почему язык программирования должен быть статичным? Ruby — один из самых динамичных среди существующих языков.

С некоторыми оговорками я бы выделил и такой аспект: «Не будьте рабом производительности». Если производительность оказывается недопустимо низкой, проблему придется решать, но не следует с самого начала выводить ее на первый план. Предпочитайте элегантность эффективности в тех случаях, когда эффективность не слишком критична. Впрочем, когда вы пишете библиотеку, которая будет использоваться непредвиденными способами, о производительности следует задуматься с самого начала.

Когда я смотрю на язык Ruby, то вижу равновесие между разными проектными целями, вижу сложное взаимодействие, напоминающее о задаче n тел в физике. Я могу представить себе, что он моделировался как мобил Александра Кальдера. Быть может, больше всего завораживает само взаимодействие, гармония, лежащая в основе философии Ruby, а не отдельные составные части. Программисты знают, что их ремесло — не просто сплав науки и технологии, но еще и искусство. Мне неловко говорить, что в компьютерных дисциплинах есть какой-то духовный аспект, но — строго между нами! — он безусловно присутствует. (Если вы не читали книгу Роберта Пирсига «Дзен и искусство ухода за мотоциклом» (Robert Pirsig, Zen and the Art of Motorcycle Maintenance), горячо рекомендую.)