Разработчик, тимлид и ведущий IT Way Podcast Павел Калашников рассказывает, почему он очень любит работать с Ruby и можно ли программировать, ненавидя этот процесс.
- Ruby не медленный
- Ruby крутой
- В Ruby действительно все — объекты
- Это все игрушки
- Ruby поможет вам приходить в другие языки
- RUBY MERTV
Разработчики проводят в IDE по несколько часов пять дней в неделю. Я не психолог, но подозреваю, что жизнь программиста будет намного лучше, если ему нравится писать код.
Если разобрать факторы, которые влияют на получение удовольствия от программирования (именно формата человек-машина), получается такой список:
- IDE
- Качество кода, с которым приходится работать
- Качество окружения, в котором этот код исполняется
- Сам язык программирования
Когда-нибудь мы поговорим о том, как важны IDE, качество кода и окружение для настроения работать. Сегодня я расскажу про самый приятный язык программирования и почему он на самом деле крутой.
Оффтоп: ниже находится видео с публичным собеседованием на Ruby-разработчика моего старого другана Ильи Шакирова, смотрите его сейчас или немного попозже (после прочтения статьи, например):
Ruby не медленный
Плохие программисты обычно начинают обсуждение Ruby с фразы «Ruby — медленный». Что медленное? Язык? Как язык программирования может быть медленным? Медленными могут быть компилятор, интерпретатор или среда исполнения. Как показывает практика, программисты, которые начинают обсуждение с этой фразы, обычно не разделяют этих терминов. Это плохо для них: у популярных языков сегодня точно больше одной среды исполнения, а у Ruby есть аж три популярных интерпретатора: MRI (оригинальный), JRuby (исполняется на JVM) и Rubinius. У каждого свои сферы применения, критерии к измерению скорости исполнения исходного кода.
Поэтому нельзя однозначно заявлять, что Ruby — медленный. Можно обратить внимание на скорость работы его интерпретаторов, и уже тогда это будет интересный разговор.
Кстати, когда вы выясните, какие компиляторы и интерпретаторы есть у вашего языка программирования, то приятно удивитесь, насколько широкий мир откроется перед вами.
Простите, наболело за годы. Сколько раз я это людям объяснял, не посчитать. Теперь хоть эту статью буду сразу скидывать. Фууууух, выдохнули и пошли к приятному.
Ruby крутой
Так как это мнение автора статьи, то давайте рассмотрим моменты, которые мне за 10 лет программирования на Ruby не надоели. Важный момент, автор статьи не утверждает, что эти преимущества есть только в Ruby, но в Ruby они точно есть. Сейчас я буду писать очевидные вещи, о которых, кажется, все забыли.
Скобки, точки с запятой и блоки кода
Благодаря возможности не писать скобки и точки с запятыми, а также потрясающему синтаксису блоков кода, мы можем писать по-настоящему чистый код.
Ниже я покажу два варианта написания кода: первый — без скобок и точек с запятыми; второй — со скобками и точками с запятыми. В примерах скобки намеренно расставлены неверно с точки зрения Ruby, потому что в других языках подобный код выглядел бы действительно так.
Первый скриншот — песня, а не код. Посмотрите, как уютно и красиво все устроено. Будто бы мы на английском языке объясняем компьютеру, что нужно делать.
DSL
Domain Specific Language — язык, ориентированный на конкретную предметную область. Подробнее про DSL можно почитать тут. Отмечу, что рубисты любят создавать DSL не только в рамках фреймворков, но и в своих проектах.
Посмотрим еще раз на пример, который был выше:
state_machine :review_state, initial: :unviewed do
state :unviewed
state :approved
state :declined
event :approve do
transition unviewed: :approved
after do
send_message_to_user
end
end
end
Разработчику не нужно знать Ruby, чтобы понять, что делает этот код. Это описание стейт-машины, которая призвана управлять процессом ревью какого-то объекта.
Из-за чистоты кода рубисты легко создают DSL, чтобы писать такой красивый код. Более того, несколько лет активно развивалась идея того, чтобы показывать конечному заказчику непрограммисту исходный код тестов, написанных на Ruby с помощью фреймворка RSpec. Такой исходный код не отталкивает читателя кучей ненужных символов, а чем-то он даже похож на текст на английском языке.
За свою карьеру мне несколько раз удавалось такое делать — круто, когда можно показать, как работает та или иная функция с помощью исходного кода теста.
Инициализация, присвоение, возвращение
Ruby по умолчанию возвращает из функции последнее присвоенное или вызванное значение. Для этого можно даже не использовать ключевое слово return
.
def view_by_value_type(value)
case value.class
when Date
date_view value
when Fixnum
fixnum_view value
when MyCustomTextType
my_custom_text_type_view value
else
default_view value
end
end
Эта функция возвращает результат исполнения функции что-то-там_view
. Хотя в коде не используется ключевое слово return
.
Из приятных фишек Ruby при инициализации переменных есть вот такая штука:
url ||= 'hexlet.io'
Оператор ||=
присвоит значение url
только в том случае, если url
имеет пустое значение или вообще не был объявлен до этого. Если в url
уже есть какое-то значение, переприсвоения не будет.
Такой оператор решает огромное количество проблем, связанных с инициализацией новых переменных.
Методы со знаком вопроса
В стандартной библиотеке Ruby есть огромный набор функций, которые позволяют сделать код лучше и читабельнее. Мои любимые методы из стандартной библиотеки — методы со знаком вопроса.
Как проверить, что x
равен 0? Очевидно, что метод ==
: x == 0
, а кто-то скажет x === 0
. И при первом приближении все будут правы.
А рубист просто скажет x.zero?
. И знаете, почему? Просто потому что он может.
Для чисел существует огромный набор методов со знаком вопроса: zero?
, nonzero?
, real?
, positive?
, negative?
, between?
, infinity?
, finity?
и т.д. Получается, что покрыты практически все стандартные действия.
Рубист даже может сам создавать методы со знаком вопроса. Название методов в Ruby поддерживает знак вопроса, а по конвенциям кода такие методы должны возвращать значения true
, false
(еще nil
и любой другой объект на самом деле, но чтобы это понять, пройдите профессию по Ruby на Хекслете).
Метапрограммирование
Если в гугле найти определение термина «Метапрограммирование», можно увидеть несколько разных понятий из различных источников. Мое любимое описание этого термина: это вид программирования, когда код используется как данные. Как это?
Возьмем пример выше:
def view_by_value_type(value)
case value.class
when Date
date_view value
when Fixnum
fixnum_view value
when MyCustomTextType
my_custom_text_type_view value
else
default_view value
end
end
В этом коде мы работаем с данными в переменной value
. Чуть дальше я покажу, когда код можно использовать как данные. Представленный ниже пример сильно упрощён, использовать такой код в реальных проектах не стоит. Но сам принцип можно применять в разработке.
def view_by_value_type(value)
type = value.class.underscore
send((type + "_view"), value)
end
Этот код делает ровно то же самое, что блок выше. Его можно записать чуть поэлегантнее и в одну строку, но я специально разделил на две, чтобы было понятнее.
- Строка
type = value.class.underscore
. Берем название класса переменнойvalue
и меняемcamelcase
наsnake-case
, потому что снейк-кейсом пишутся названия методов (это можно увидеть в первом блоке кода). - Строка
send((type + “_view”), value)
. Она прибавляет к названию типа в снейк-кейсе слово_view
, после чего мы получаем название метода. Методsend
вызывает метод по полученному названию и отправляет в него аргументvalue
.
В итоге если у переменной value
будут появляться новые типы, мы не станем менять эти две строки кода, а просто добавим методы type +
“view”в пространство исполнения этого кода. Например, если понадобится обработать дополнительно тип Image, мы просто создадим метод
image_view` в пространстве исполнения и наш заработает _автоМАГически.
То есть мы фактически смешали исходный код с данными, которые он обрабатывает. Сильное смешивание может привести к сложным последствиям, но в небольших количествах — это чудеса!
Читайте также: Как полтора года я безуспешно проходил собеседования на PHP-разработчика, а в итоге стал программистом на Ruby on Rails
В Ruby действительно все — объекты
Вы заметили, выше я назвал ==
методом, хотя такие вещи принято называть операторами?
У меня есть доказательство, что это точно метод.
Откройте REPL для Ruby в онлайне. Перед тем, как мы начнем писать код, давайте вспомним, что в Ruby — все объекты. То есть число 0 в Ruby — объект. У нормальных объектов всегда есть методы, и в Ruby легко можно это узнать.
Чтобы посмотреть список имен доступных методов объекта, вызываем метод methods
. Для этого надо написать в левом окне puts 0.methods
. Метод puts
в Ruby — это в базовом представлении «напечатай в стандартном терминале».
Нажимаем клавишу Run. В правом окне видим результат выполнения кода, то есть список методов объекта 0
. В этом списке явно виден ==
.
Это просто указание, что в списке методов есть ==
, а не доказательство, что ==
— метод. Может быть, результат этой команды еще и оператора показывает.
Как доказать, что ==
— действительно метод. В Ruby действительно все объекты, поэтому мы получим объект метода ==
с помощью следующего кода:
С правой стороны этот непонятный вывод указывает, что перед нами объект метода ==
у класса Integer, коим является 0
. А какой же класс у объекта ==
?
Это уже точно нам говорит, что класс объекта ==
называется Method. То есть это точное доказательство, что ==
в Ruby — метод, потому что он — объект класса Method.
Дальше хочу показать, какой класс у объекта класса объекта метода ==
класса Integer. Да, в предыдущем предложении нет опечатки, перечитайте его ещё несколько раз, чтобы понять, о чём мы говорим.
И знаете что? Этот класс называется внезапно Class.
Какой класс у объекта класса объекта класса метода ==
класса Integer вы узнаете сами. Просто перейдите в Repl.It и пробуйте. Помимо этого, у каждого класса есть родительские классы.
Это все игрушки
Это правда — все примеры, про которые я рассказывал выше — обычные игрушки. Но самое главное, что эти возможности применимы в реальных проектах. Я лично использовал их сотни, если не тысячи раз. Более того, такие широкие возможности по управлению кодом и метапрограммированию мотивируют программистов создавать новые инструменты, библиотеки и фреймворки. Так что в Ruby делать опен-сорс действительно весело!
Ruby поможет вам приходить в другие языки
Ruby не должен быть первым языком программирования (об этом мы расскажем в другом материале). Это золотое правило, которое нужно соблюдать.
Зато после Ruby гораздо легче будете переходить на другие языки программирования, ведь потренировавшись в написании сложного контекстно-зависимого кода, разработчик обычно чувствует себя хорошо в других языках. Самое главное — избавиться от синдрома рубиста при переходе и принять тот факт, что свободы в большинстве других языков программирования становится меньше.
После Ruby вам будут открыты все парадигмы программирования. Императивное программирование можно познать при написании скриптов и коротких программ в Ruby. Объектно-ориентированное программирование — благодаря свободной объектной модели Ruby. И на нем даже можно создавать код, основанный только на функциях. Такой подход позволит легче прийти в функциональную парадигму программирования.
RUBY MERTV
Слышу об этом постоянно последние восемь лет, а компании до сих пор продолжают набирать рубистов, новые крутые продукты пишутся на Ruby. Фреймворки и библиотеки до сих пор стараются обогнать всю остальную индустрию — как пример, новинка под названием Hotwire, которую представили в прошлом году в очередном обновлении Ruby on Rails. И если все сложится хорошо, то возможно, что в ближайшие годы она устроит вторую революцию в веб-разработке. Так что Ruby живёт!
Если эта статья нормально зайдет в Хекслет-коммьюнити, я напишу материал о том, какие сферы применения для Rails сегодня самые предпочтительные и где этот фреймворк уделывает на две головы все остальные веб-фреймворки.
Никогда не останавливайтесь: В программировании говорят, что нужно постоянно учиться даже для того, чтобы просто находиться на месте. Развивайтесь с нами — на Хекслете есть сотни курсов по разработке на разных языках и технологиях