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

Я начал с создания метода для получения пользовательского ввода, который предлагал пользователю ввести предположение и сохранял его в переменной. Затем я создал пару операторов if/else, чтобы дать пользователям обратную связь, если они ввели что-то недопустимое. Если они ввели слишком много или слишком мало символов, это выдаст им сообщение об ошибке длины. Если бы они ввели цвета, которые не являются вариантами, это выдало бы им сообщение об ошибке цвета. Это работало нормально, но затем я получил отзыв от очень полезного Кайла Аннена о том, что вместо этого я мог бы использовать рекурсивное защитное предложение.

Что это делает, так это устанавливает вызов, который будет вызван, если будут выполнены критерии функции. В качестве примера мы будем использовать код, который я написал для Mastermind (защитное предложение находится в строке 38).

Это вызывает метод get_input, если либо length_error, либо color_error оцениваются как true. Каждый из этих методов определяет правильность ввода и возвращает false оператору защиты, если ввод верен. Если ввод недействителен, он puts выводит соответствующее сообщение об ошибке и возвращает true в защитное предложение в строке 38, таким образом перебирая get_input до тех пор, пока не будет введено правильное предположение. Предложения Guard также используются в строках 57 и 67, чтобы не загромождать length_error и color_error.

Защитные операторы — отличный способ избавиться от громоздких вложенных условий, когда у вас есть несколько ветвей if/else. Чтобы проиллюстрировать эту концепцию более простым примером, следующие фрагменты кода делают то же самое.

if true
  puts "Hello, World!"
end

puts "Hello, World!" if 
true

Использование защитных предложений помогло мне избавиться от беспорядочных операторов if/else, и их просто приятно использовать. Я уверен, что они не идеальны для каждого приложения, но я, безусловно, их поклонник. Подробнее о защитных предложениях читайте на Refactoring.com