Код
#статьи

Язык стартапов родом из Японии: знакомимся с Ruby

Senior-разработчик на Ruby рассказывает, как устроен язык и что на нём пишут, сколько зарабатывают «рубисты» и почему Rails — революционный фреймворк.

Иллюстрация: Катя Павловская для Skillbox Media

Александр Зутиков


Шесть лет программирует на Ruby on Rails, до этого пару лет работал fullstack-разработчиком на PHP. Собеседует кандидатов и читает авторский курс по Ruby on Rails для стажёров компании, в которой работает. Пропагандирует Fedora Linux. 


Ссылки


Ruby — это объектно-ориентированный язык общего назначения с динамической типизацией. Он появился в Японии в 1995 году и быстро завоевал там популярность. Однако из-за отсутствия документации на английском языке мир узнал о нём лишь пару лет спустя.

Юкихиро Мацумото, создатель Ruby
Фото: Wikimedia Commons

Создатель Ruby Юкихиро Мацумото (Matz) изначально создавал язык понятным для людей, а не для машин. Он считал, что разработчики должны получать удовольствие от работы и быть продуктивными, а не бороться с дизайном языка.

Особенности Ruby

В основном Ruby применяется в веб-разработке — нишу языка определил удачный фреймворк, Ruby on Rails. Но есть и другие направления: скрипты, деплоймент, безопасность и так далее.

Ruby лаконичный, и у него приятный синтаксис. Там, где на другом языке приходится писать много ненужного кода, в Ruby можно обойтись парой строчек. За лаконичность и приятный синтаксис на первых порах пришлось платить производительностью. Но сегодня по производительности программ Ruby не уступает таким динамическим языкам, как Python и JavaScript.

Синтаксис Ruby одновременно напоминает Python, Perl и немного Pascal — из-за открывающих и закрывающих блоков. Ruby также повлиял на некоторые языки программирования. Например, создатели Elixir и Crystal вдохновлялись его синтаксисом.

Сравним код программы Hello World! на Ruby и C++.

Код на Ruby:

puts "Hello, World!"

Код на C++:

#include <iostream>
int main() 
{
std::cout << "Hello, World!" << std:endl;
return 0;
}

На Ruby можно без проблем перейти с любого языка. Но легче всего будет тем, кто уже имел дело с динамически типизированными языками — например, с Python. А если вы переходите со статически типизированного языка, то всегда помните о duck typing.

Duck typing означает, что если объект ведёт себя как утка и крякает как утка, то он и есть утка. Например, если у объекта есть какие-то методы, характерные для строк, то Ruby будет считать этот объект строкой. Поэтому всем, кто переходит с языков со статической типизацией, нужно сначала привыкнуть и не пытаться жёстко контролировать типы.

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

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

Ещё с динамическими языками мы не думаем об утечках памяти: не выделяем её и не описываем типы. Мы объявляем класс и пишем код внутри, а дальше язык сам следит за всеми манипуляциями с памятью.

Где применяют Ruby

Ruby больше всего подходит для веб-разработки. На нём написано много приложений в сфере e-commerce, SaaS-решений, биржевых площадок и других сложных проектов. Единственное, для чего Ruby не подходит, — это real-time-приложения. Они требуют работать с сокетами и последовательно идентифицировать пользователей, а у Ruby с этим проблемы.

Стартапы часто используют Ruby, потому что на нём можно быстро проверять идеи. В связке с Rails это просто идеальный язык для создания прототипов и MVP. Откройте сайт Y Combinator, и вы увидите, что 8 из 10 топовых проектов написаны именно на Ruby on Rails.

Люди выбирают эту технологию, потому что она позволяет быстро делать проекты, вовлекать новых разработчиков и пилить функциональность и фичи, а потом тестировать их и выкатывать.

Известные компании — GitHub, GitLab, Shopify, Airbnb, SoundCloud, Dribbble, Kickstarter и Stripe — тоже внедряют Ruby в свои проекты. Есть и те, кто использует Ruby, но не афиширует это.

Что у Ruby «под капотом»

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

У такого подхода есть преимущества:

  • мы не привязываемся к платформе — достаточно установить интерпретатор, чтобы запустить код;
  • не нужно описывать типы данных — за это отвечает динамическая типизация;
  • проще добавлять новые возможности и фичи.

Но также есть и недостатки:

  • относительно низкая скорость выполнения;
  • ошибки, связанные с типами.

Давайте разберёмся, как Ruby работает изнутри. Допустим, у нас есть Ruby-файл со строкой — «puts 1 + 2». Что делает интерпретатор?

Сначала он считывает файл целиком, а потом разбивает код на токены: «puts», « », «1», « », «+», « » и «2». Заметьте: пробел сохраняется в отдельном токене.

После этого Ruby запускает лексический анализатор, который должен проверить и добавить дополнительные параметры для каждого токена. Он берёт первый — «puts» — и добавляет к нему специфичные параметры, чтобы компьютер понял, что нужно дальше с ним делать. И так для каждого токена.

Затем запускается парсер для составления абстрактного дерева — пути исполнения кода. И завершающий шаг: Ruby переводит это дерево в низкоуровневый байт-код, понятный виртуальной машине Ruby, и запускает его. Если на каком-то из этапов происходит ошибка, то запускается Ruby-код, который выводит эту ошибку.

Итак, вот что делает Ruby:

  • считывает файл;
  • разбивает его на токены;
  • запускает лексический анализ для дополнительной информации;
  • запускает парсер для AST-дерева;
  • переводит дерево в низкоуровневый байт-код;
  • исполняет код.

Как и куда Ruby развивается

Новые версии Ruby выходят практически каждый год. Недавно вышла третья версия, в которую добавили возможность переписывать нотации типов в отдельных файлах. В чём смысл?

В статически типизированных языках типы можно описывать прямо в коде, но Matz, создатель Ruby, решил, что это плохой путь: добавить типы в язык легко, а вот убрать потом — трудно. Matz верит, что в скором будущем появятся инструменты, которые сами будут определять тип на лету. Он не хочет добавлять статическую типизацию прямо в код. Поэтому в третьей версии появилась типизация в отдельных файлах и pattern matching — как в Elixir. Также в Ruby v3 добавили Ractors — инструмент для параллельного запуска программ, новый JIT‑компилятор для ускорения выполнения кода и статический анализатор типов — typeof.

А ещё улучшили REPL: добавили подсветку синтаксиса, автодополнение и «быструю документацию», переработали вывод некоторых ошибок и разработали новые дебаги.

Думаю, команда Ruby будет усерднее работать над ускорением языка, потому что компании пишут всё больше сложных проектов на Ruby on Rails. Например, сейчас Shopify улучшает свой YJIT‑компилятор, чтобы в несколько раз повысить производительность приложений на Rails, — обычный компилятор умеет оптимизировать только чистый Ruby-код.

Думаю, в будущем Ruby получит больше встроенных инструментов и начнёт заимствовать синтаксические конструкции из других языков, таких как JavaScript с его стандартами ES6, ES7 и так далее.

Какие у Ruby есть проблемы

Да никаких. Он же идеален! Ну, почти… :)

Конечно, у Ruby, как и у других языков, есть минусы. Основные — GIL и потребление памяти.

GIL — Global Interpreter Lock. Из-за него мы не можем эффективно использовать ядра процессора. Например, у меня есть 16-ядерный процессор. Я запускаю вычисления нескольких потоков, чтобы программа посчитала на каждом потоке какие-то формулы. Запускаются потоки. Сначала один поток работает с одним ядром. Затем он останавливается и сохраняет состояние, а процесс переключается на другой поток, который тоже использует одно ядро. Остальные ядра при этом бездействуют.

Получается, из 16 ядер всегда будет использоваться только одно. А происходит это потому, что Ruby создавался во времена, когда у процессоров было всего одно ядро. Сейчас команда Ruby занимается этой проблемой.

Работа Ruby с памятью. Язык практически не отдаёт её обратно — даже если она не используется. Допустим, вы запустили приложение: через час оно ест два гигабайта, а через два часа — четыре. Это преувеличение, но программы на Ruby работают примерно так.

Внутри это происходит следующим образом. Ruby делит память на участки фиксированной длины — страницы. Страницы, в свою очередь, делятся на слоты. Представим, что я создал приложение, которому нужно четыре слота, а на странице свободно всего три. Тогда Ruby выделит новую страницу и на ней заполнит четыре слота, а слоты с предыдущей страницы будут пустовать. При этом, если на странице занят хотя бы один слот, Ruby не освободит память из-под неё.

Какие у Ruby есть инструменты

IDE. Для разработки на Ruby подойдёт любой расширяемый редактор кода — VS Code, Vim, Emacs, Sublime Text, Atom. Но если нужна полноценная IDE, то можно использовать платную RubyMine.

На данный момент для работы я использую RubyMine, а для pet-проектов VS Code и Neovim.

Vim как IDE для Ruby
Источник: SpaceVim

Тесты. Для тестов есть классный и богатый фичами фреймворк RSpec, который уже стал стандартом в сообществе. В самом Ruby есть встроенные MiniTest и TestUnit.

Ruby-стандарты. Сообщество создало общий стандарт для написания кода, который называется RuboCop. Ещё есть гайды на сайте rubystyle.guide. Всё это находится в открытом доступе — пользуйтесь и пишите идеальный код. А если стандарты сообщества вас не устраивают, то можно локально добавить свои.

Другие утилиты. Программисты любят Ruby, потому что у него очень богатая экосистема — разнообразные библиотеки, менеджеры зависимостей (Bundler), менеджер пакетов (RubyGems), встроенный менеджер тасков Rake, интерактивные среды программирования и дебаггеры (IRB). Если этого не хватает, можно добавить Pry-дебаггер.

Для продвинутых программистов есть утилиты, которые позволяют строить AST-деревья и смотреть, как Ruby-дебаггер работает на уровне C-кода. На RubyGems и Ruby Toolbox можно посмотреть «джемы». А если не нашли ничего подходящего, то можете создать свой джем и выложить его на один из этих сайтов.

С помощью утилит Ruby Version Manager (RVM) и ASDF можно установить несколько версий языка и управлять зависимостями. А Sidekiq позволяет обрабатывать фоновые задачи — это одна из самых популярных и стабильных библиотек.

Что такое Ruby on Rails

Большой популярности Ruby добился благодаря фреймворку Ruby on Rails — в нём были фичи, которыми не обладали другие фреймворки.

Rails — это fullstack-фреймворк для разработки приложений любой сложности. Его создала компания 37signals (в прошлом Basecamp) в 2005 году и тем самым привнесла много нового в мир веб-разработки.

Например, в Rails появились обратимые миграции баз данных — это когда мы можем сделать миграцию, а потом откатить все изменения парой команд. Не менее революционной фичей было сжатие тела CSS-кода — Asset Pipeline.

Главная проблема большинства фреймворков тех времён была в том, что у них не было единой системы конфигурирования и настройки приложений. Rails привнёс понятие convention over configuration, появилась единая и понятная структура. Программисты стали использовать это соглашение и писать проекты на Ruby гораздо быстрее. Появлялось всё больше видеоуроков, возникали локальные сообщества, проводились конференции по Rails. Одним словом — Ruby взлетел.

Со временем Ruby сдал позиции как fullstack-фреймворк. Во фронтенде появились более крутые конкуренты — React, Vue.js и Angular. В итоге Rails стали использовать в основном только в бэкенде. Но недавно вышедшая версия Rails 7 кардинально изменила ситуацию: разработчики добавили поддержку ECMAScript 6 и HTTP/2.0. Теперь для запуска фронтенда не нужно устанавливать Node.js. Раньше это было немыслимо.

В седьмой версии Rails также появилась новая киллер-фича — Hotwire for Rails. Это когда отправка HTML проходит по сокету: открывается сокет-канал и по нему приходит HTML-файл. Фреймворку больше не нужно делать отдельные запросы на бэкенд — достаточно просто подписаться на сокет. А ещё недавно создатели Ruby on Rails выпустили фреймворк Stimulus, который позволяют программисту меньше работать с JavaScript-кодом.

В общем, Rails всё ещё остаётся самым широко используемым Ruby-фреймворком. Есть ещё Hanami и Sinatra, но они обладают рядом недостатков, которых нет у Rails.

Сколько платят разработчикам на Ruby

Сейчас рубисты очень востребованны. Статистику по зарплатам можно посмотреть на канале Jooby. Судя по данным с этого канала, в СНГ ситуация такая:

  • джуниор — до 1000 долларов;
  • джуниор+ — от 1000 до 2000 долларов;
  • мидл — от 2000 до 4000 долларов;
  • сеньоры — от 4000 до 7000 долларов;
  • сеньоры, которые работают с заказчиками напрямую, — от 4500 до 9500 долларов.

Что почитать и посмотреть начинающим рубистам

Книги. Начинающим рекомендую прочитать три базовые книги. Из них вы узнаете, как работает язык, освоите его объектную модель и метапрограммирование:

Джуниорам и выше я тоже советую изучить метапрограммирование и объектно-ориентированный дизайн при работе с Ruby, чтобы понять, как делать инверсию зависимостей, соблюдать принцип единственной ответственности, или SOLID. Также изучите внутреннее устройство Ruby: как он парсит данные, как запускается и работает его виртуальная машина. Ответы на эти вопросы вы найдёте в следующих книгах:

Рассылки. Получать новости о Ruby можно в еженедельной рассылке Ruby Weekly, это позволяет оставаться «на волне». Также есть рассылка Random Ruby и This Week in Rails — последнюю ведут создатели Rails.

Telegram-каналы:

YouTube-каналы:

Новичкам советую в первую очередь разобраться с концепцией языка и объектной моделью — и только потом приступать к изучению фреймворков. Иначе будет казаться, что Rails — это магия. На самом же деле это всего лишь метапрограммирование и много чего ещё.

Тем, кто планирует сменить стек, скажу, что Ruby on Rails — это действительно крутой инструмент. Переходите на него, пробуйте и получайте кайф от разработки. А если этот фреймворк надоест — вы всегда можете перейти на другой. Воспринимайте языки программирования и фреймворки как инструменты, которые облегчают жизнь, и не зацикливайтесь на чём-то одном.

Хорошему программисту должно быть всё равно, на какой стек переходить. Сегодня мы пишем на одном языке, а через месяц — на другом. Будьте Software Engineer, который может разобраться во всём.

Изучайте IT на практике — бесплатно

Курсы за 2990 0 р.

Я не знаю, с чего начать
Научитесь: Профессия PHP-разработчик с нуля до PRO Узнать больше
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована