Условия: if, unless, тернарный оператор
Условия — это развилки, на которых программа выбирает путь. Ruby даёт их в нескольких формах, и у каждой свой характерный стиль использования.
Суть:ifвыполняет ветку, когда условие истинно;unless— это «если НЕ»; а условие-модификатор в конце строки делает простые проверки лаконичными.
Базовая конструкция знакома по любому языку, но в Ruby есть нюанс: if — это выражение, а не инструкция. Оно возвращает значение, и это значение можно присвоить переменной. Эта мелочь меняет стиль кода: вместо громоздких присваиваний в каждой ветке вы пишете одно.
score = 75
grade =
if score >= 90 then "отлично"
elsif score >= 70 then "хорошо"
elsif score >= 50 then "удовлетворительно"
else "неуд"
end
puts grade # => хорошо
Разбор: unless и модификаторы
unless условие равнозначно if not условие, но читается естественнее в случаях вроде «выполни, если НЕ пусто». А когда тело — одна строка, Ruby позволяет вынести условие в конец: это «модификатор условия», очень характерный для языка приём.
puts "Доступ запрещён" unless logged_in
send_email if user.subscribed?
return nil if list.empty?
# тернарный оператор — короткое if/else
status = age >= 18 ? "взрослый" : "несовершеннолетний"
Как работает под капотом
Поскольку if — выражение, оно всегда что-то возвращает. Если ни одна ветка не сработала и нет else, результатом будет nil. Понимание потока управления помогает писать чище: вы выбираете форму под задачу.
[ условие ]
/ \
истина ложь
| |
ветка then elsif? --> ещё условие
| |
| else / nil
\ /
\ /
результат if
(его можно присвоить!)
Та же логика «выбор значения по условию» на Python выражается тернарным оператором:
# Та же логика на Python ▶
score = 75
grade = ("отлично" if score >= 90
else "хорошо" if score >= 70
else "удовлетворительно" if score >= 50
else "неуд")
print(grade) # хорошо
Частые ошибки
- Двойное отрицание.
unless !activeчитается мучительно. Используйтеif active. - unless с elsif. У
unlessне бываетelsif— это запутывает. Для нескольких веток беритеif. - Слишком длинный тернарник. Вложенные
? :нечитаемы. Если веток больше двух — пишите обычныйif.
Best practices
- Для простых одностраничных проверок используйте модификатор:
raise "ошибка" if invalid. - Применяйте «ранний возврат» (guard clause):
return if list.empty?в начале метода вместо вложенныхif. - Помните, что
ifвозвращает значение — присваивайте результат напрямую, не дублируя присваивание в ветках.
Глубже: условия как часть выразительного стиля
Условные конструкции в Ruby — это место, где особенно ясно видна философия «код для людей». Возьмём приём guard clause: вместо того чтобы оборачивать всё тело метода в большой if и уезжать вправо вложенными блоками, опытный рубист в начале метода отсекает «плохие» случаи ранними возвратами. Метод читается как список предусловий, а затем — основная логика на нулевом уровне вложенности. Это резко снижает когнитивную нагрузку. Другой характерный приём — использование того факта, что if возвращает значение: вы не дублируете присваивание в каждой ветке, а присваиваете результат всей конструкции один раз. Сюда же относится привычка предпочитать позитивные условия негативным: if valid? читается легче, чем unless invalid?, а двойные отрицания вроде unless !ready вообще под запретом. Все эти мелочи по отдельности кажутся косметикой, но вместе они определяют, будет ли ваш код через полгода понятен вам же и коллегам. Хороший условный код — плоский, позитивный и без дублирования.
Итог. В Ruby if/unless — это выражения, возвращающие значение. Модификаторы условий и guard clause делают код плоским и читаемым, а тернарный оператор хорош ровно для двух коротких веток.