Защитные условия
Понятные досрочные возвраты
«Защитные условия» — бесплатный урок Ruby Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Ruby Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Ruby Academy содержит 4 уроков всего.
Чистые досрочные возвраты
Защитная конструкция — это проверка в начале метода, которая досрочно возвращает результат для недопустимых или крайних случаев. Она сохраняет основную логику плоской и удобной для чтения.
def greet(name)
return "Hello, stranger" if name.nil?
"Hello, #{name}"
end
puts greet(nil)
puts greet("Ada")Проблема: глубокая вложенность
Без защитных конструкций проверки накапливаются во вложенных блоках if. Основная работа оказывается глубоко спрятанной у правого края экрана.
def charge(user)
if user
if user[:active]
puts "Charging #{user[:name]}"
end
end
end
charge({ name: "Sam", active: true })Решение: защитные конструкции
Инвертируйте каждое условие и возвращайте результат досрочно. Теперь основной сценарий находится на базовом уровне отступов, не вложен и сразу заметен.
def charge(user)
return unless user
return unless user[:active]
puts "Charging #{user[:name]}"
end
charge({ name: "Sam", active: true })return без значения
Простой return завершает метод и возвращает nil. Используйте его, когда вызывающему коду не нужен результат для отклонённого случая.
def log(message)
return if message.nil? || message.empty?
puts "LOG: #{message}"
end
log("")
log("started")Возврат значения
Защитная конструкция также может возвращать содержательное значение, например разумное значение по умолчанию, чтобы вызывающий код всегда получал пригодный результат.
def discount(price)
return 0 if price <= 0
price * 0.1
end
puts discount(-5)
puts discount(200)Защита с помощью unless
return unless condition читается так: «выйти, если это требование не выполнено». Это одна из самых распространённых идиом Ruby.
def withdraw(balance, amount)
return "Insufficient funds" unless balance >= amount
"New balance: #{balance - amount}"
end
puts withdraw(100, 150)
puts withdraw(100, 40)Несколько защитных конструкций
Объединяйте несколько защитных конструкций, чтобы последовательно проверять входные данные. Каждая строка формулирует одно правило, благодаря чему метод сам себя документирует.
def register(name, age)
return "Name required" if name.to_s.empty?
return "Must be 18+" if age < 18
"Registered #{name}"
end
puts register("", 30)
puts register("Lee", 16)
puts register("Lee", 21)Защитные конструкции с next в циклах
Внутри блока или цикла нельзя использовать return, чтобы пропустить только одну итерацию. Используйте next как защитную конструкцию для перехода к следующему элементу.
[1, -2, 3, -4].each do |n|
next if n.negative?
puts n
endЗащитные конструкции повышают удобочитаемость
Мысленно сравните два приведённых ниже стиля: защитные конструкции убирают else и уменьшают вложенность. Читатель сначала видит обработку недопустимых случаев, а затем основную логику.
def area(width, height)
return 0 unless width.positive? && height.positive?
width * height
end
puts area(0, 5)
puts area(4, 5)Возбуждение исключения в защитной конструкции
Если некорректные входные данные — это ошибка программиста, а не ожидаемый случай, возбудите исключение в защитной конструкции, чтобы быстро и явно завершить выполнение.
def sqrt(n)
raise ArgumentError, "n must be >= 0" if n.negative?
Math.sqrt(n)
end
puts sqrt(16)
puts sqrt(-1) rescue puts "caught negative input"Объединяем всё вместе
Защитные конструкции — небольшая привычка с большим эффектом:
- Обрабатывайте крайние случаи в начале и возвращайте результат.
- Оставляйте основную логику без вложенных отступов.
- Используйте
return/next/raiseв зависимости от ситуации.
def initials(name)
return "" if name.nil? || name.strip.empty?
name.split.map { |part| part[0].upcase }.join
end
puts initials(" ").inspect
puts initials("grace hopper")Быстрая проверка
Проверьте, насколько хорошо Вы понимаете защитные конструкции.
Итоги
Вы изучили защитные конструкции:
- Возвращайте результат досрочно для недопустимых или крайних случаев.
return unlessзавершает выполнение, когда требование не выполнено.- Используйте
next, чтобы пропустить итерацию цикла, аraise— для настоящих ошибок. - В результате методы становятся плоскими и сами себя документируют.
def safe_divide(a, b)
return nil if b.zero?
a / b
end
puts safe_divide(10, 0).inspect
puts safe_divide(10, 2)Часто задаваемые вопросы
Урок «Защитные условия» бесплатный?
Да — полный текст урока «Защитные условия» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Ruby Academy, подпишись на CoddyKit PRO. Курс Ruby Academy содержит 4 уроков всего.
Чему я научусь в уроке «Защитные условия»?
Понятные досрочные возвраты Ты практикуешь Ruby Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Ruby Academy?
Предыдущий опыт не требуется. Ruby Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Защитные условия»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Ruby Academy?
Да. Каждый урок Ruby Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.