Условия: 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 делают код плоским и читаемым, а тернарный оператор хорош ровно для двух коротких веток.

Проверьте себя
1. Почему в Ruby можно написать grade = if ... else ... end?
AЭто синтаксическая ошибка
BПотому что if в Ruby — это выражение, которое возвращает значение
Cif всегда возвращает true
DТак работает только unless
2. Чему равнозначна конструкция unless condition?
Aif condition
Bif not condition
Cwhile condition
Duntil condition