В 2008, когда я ещё учился на инженера-разработчика, двое моих друзей решили запустить проект под названием Feedbooks. Суть проекта состояла в создании электронной библиотеки, которая содержит как признанные шедевры мировой литературы, так и самиздат. При этом хотелось, чтобы библиотека была доступной и удобной в использовании.
Сайт для таких целей должен быть быстрым, производительным и лёгким в поддержке и содержании. Тогда, посмотрев демо-видео Ruby on Rails, друзья решили попробовать именно этот фреймворк в написании сайта. Через пару недель им понадобилась помощь. Меня пригласили в команду.
Как и у многих разработчиков моего поколения, у меня уже был небольшой опыт работы с PHP и MySQL. Даже больше, я внёс вклад в развитие нескольких CMS с открытым исходным кодом. Так что я считал себя достаточно продвинутым в веб-разработке, но, тем не менее, никогда не слышал о Ruby. После просмотра видео я тоже попал под чары Ruby on Rails и использовал этот язык следующие 10 лет. Мы с друзьями воплотили нашу идею в жизнь и, кроме того, создали ещё несколько веб-приложений при помощи этого фреймворка.
Почему же Ruby?
Ruby — очень экспрессивный язык. Юкихиро Мацумото, создатель языка, преследовал одну несложную цель: оптимизация языка для лёгкой разработки. По моему мнению, цель была достигнута. Ruby — это объектно-ориентированный язык программирования. Грубо говоря, всё в этом языке — объект. Виртуальная машина Ruby преобразует каждое выражение в машинный код. Эта виртуальная машина постоянно улучшается и с каждым новым обновлением процесс преобразования кода становится всё быстрее. Объекты в языке взаимодействуют друг с другом при помощи отправки сообщений с названием функции и аргументами. Также, Ruby очень прост с точки зрения понимания, так как эти сообщения можно модифицировать или создавать специальные интерфейсы.
Все эти особенности делают его потенциальной основой для создания предметно-ориентированных языков (DSL). Этим и воспользовался Дэвид Хайнемир Ханссон при создании Rails. Ruby on Rails представляет собой набор DSL и фреймворк для создания веб-приложений. На сегодняшний день он отлично приспособлен для создания приложений, в которых главные составляющие части — это логика и моделирование бизнес-процесса.
И, 6 лет спустя, когда я стал работать в Sqreen, мне показалось логичным продолжать использовать Ruby. Но, всё же, для написания бэкенда мы использовали Python.
Ты любишь Ruby, но пишешь бэкенд на Python, почему так?
Бэкенд Sqreen представлен в качестве нескольких серверов. Первое, что видит наш новый клиент — корпоративный статичный сайт (кстати говоря, созданный на Jekyll, генераторе сайтов на Ruby). Затем он видит информационную панель, которая, наоборот, является динамичным приложением-одностраничником на React. Панель взаимодействует с API, который мы называем “бэкенд для фронтенда”. Это не единственный наш API, их гораздо больше. Но, наверное, наиболее важный из них — “бэкенд для агентов”.
До начала разработки мы решили, что будем писать все API на одном языке для того, чтобы использовать уже реализованные модели и функции в различных API. Также мы заранее поняли, что хотя бы “бэкенд для агентов” должен быть гибким и масштабируемым, так как несколько клиентов могут запрашивать связь с узлом одновременно.
Rails, который, к сожалению, довольно медленный, мы даже не рассматривали как вариант. Конечно, это не единственный способ использовать Ruby для приложений и API, есть и другие микрофреймворки, как, например, Sinatra. Это замечательный фреймворк, маленький и простой в использовании, поэтому мы могли бы писать и на нём.
Мы выбрали Python по двум причинам. Во-первых, создатели Sqreen (Pierre Betouin и Jean-Baptiste Aviat) уже имели опыт работы с этим языком и использовали его для написания внутреннего инструментала в Apple. Во-вторых, мы были уверены в том, что анализ данных будет важен для Sqreen. Ruby, в отличии от Python, совершенно не приспособлен к этому. Выбор сделан: мы используем Python и его хорошо известный микрофреймворк Flask.
Начало работы с Python
К тому моменту я уже немного работал с этим языком для создания небольших программ для трансформации данных или вычислений. Теперь же мне надо было вывести знание языка на тот уровень, на котором я мог бы писать API. К счастью, в рамках веб-разработки мало что меняется со сменой языка. HTTP, HTML, JSON так и остаются текстовыми протоколами и языками; REST тоже не меняется. Всё, чему я научился за свою карьеру, было до сих пор актуальным. Единственное, к чему пришлось привыкнуть — это формат вывода.
Связь приложений друг с другом на нижнем уровне выполняется на Ruby при помощи серверного интерфейса Rack. Он достаточно прост, так как преобразует запросы и ответы HTTP в массив. Оказалось, что такой же подход был использован в WSGI(стандарт взаимодействия программы на Python и веб-сервера). Отлично, одной проблемой меньше.
Но что же насчёт самого языка? Ruby, как я уже упомянул ранее, объектно-ориентированный язык, как и Python. Однако, ООП в Python реализовано чуть иначе, язык является больше функциональным, чем объектно-ориентированным. Это совершенно разные языки с разным синтаксисом. Например, в Ruby блоки выделяются ключевыми конструкциями begin/def end, когда в Python блоки выделяются при помощи табуляции. К этому было довольно сложно привыкнуть (и да, я больше предпочитаю то, как это реализовано в Ruby). В Ruby исключения ловятся при помощи конструкции begin/rescue/end, тогда как в Python — try/except. Самым значительным отличием для меня стала невозможность создания однострочных блоков (find, map, inject). Кстати, в современном Python можно использовать эти блоки, в основном, для выполнения эквивалентных инструкций, что делает код запутанным. Благодаря этому разработчики думают об используемом количестве циклов, что ведёт к более чистому коду. Также я узнал о некоторых неизвестных мне и стоящих обсуждения концептов. Например, контекстные менеджеры в Python позволяют чистить ресурсы, синтаксис которых способствует написанию эффективного кода.
Итак, как же я приспособился к синтаксису Python? В самом начале я практиковался при помощи Python Koans. Этот проект с открытым исходным кодом учит людей синтаксису на практике. Вам даётся кусок кода, в котором нужно что-то изменить так, чтобы он прошёл тестовое задание. С каждым разом задания усложняются. Эти тесты охватывают разные свойства языка и позволяют на практике научиться работать с самим языком. Затем я прочёл документацию. В то время, как документация Ruby порой казалась слишком сжатой, документация Python очень содержательна. Язык разделён на модули, для каждого из которых предоставлено объяснение: почему он создан, какие проблемы решает и каким образом. Что меня удивило, так это то, что в документации содержатся советы по тому, в каких ситуациях не стоит использовать тот или иной модуль. И да, конечно, там есть и примеры. Каждый, кто начинает изучать Python, обязан прочесть документацию.
Значит ли все это, что если Sqreen не использует Ruby, то и я тоже? Нет! Мне нравится Ruby и некоторая часть Sqreen написана именно на нём.
Во-первых, у нас есть агент Ruby, который помогает защищать приложения на Ruby. Разработка и поддержка агента, которой я занимался на протяжении последних трёх лет, гораздо сложнее (и интереснее!) чем всё то, что я делал до этого. Каждый агент оснащён динамическим инструментарием. Другими словами, мы пишем код, который будет менять ход программы на основании полученного зашифрованного описания, которое передаётся по проводам. Для начала мы попробовали сделать это на Ruby, но сейчас разрабатываем это же на пяти (а скоро и на шести!) языках. Это довольно нетривиальная задача и я очень рад работать с талантливыми людьми, которым интересно её решать.
Во-вторых, после создания агента и до отправки его нашим тестировщикам (нынешним клиентам), мы хотели протестировать его в условиях реальной жизни. Нам нужно было приложение, на котором мы могли бы изучать поведение агента. Как и все инженеры, мы решили сами протестировать свой код и создали небольшой интерфейс администрирования на Rails. Сейчас он используется для мониторинга работы наших агентов с целью улучшения сервиса для клиентов.
Небольшой совет
Вы Ruby-разработчик и думаете о том, чтобы начать работать с Python? Попробуйте! Он в определённой степени похож на Ruby, так что весьма скоро вы почувствуете себя в своей тарелке. Однако, в то же время он и достаточно отличается, поэтому придётся научиться новым методам, которые помогут не только в Python-разработке, но и в работе с другими языками. Сегодня многим разработчикам недостаточно знать один ЯП. Тем более, что в открытом доступе есть огромное количество ресурсов, которые позволяют нам обучаться самостоятельно.
Перевод статьи Benoit: Why and How I Switched from Ruby to Python