Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих
Шрифт:
Интервал:
Закладка:
def initialize(num : Int)
super("The number #{num} isn't even")
end
end
def half(num : Int32)
if num.odd?
raise OddNumberError.new(num)
end
num // 2
end
В этом примере мы создали класс с именем OddNumberError, который наследуется от Exception. Таким образом, его объекты могут быть вызваны и сохранены. Затем мы переписываем метод half, чтобы использовать этот более специфичный класс ошибок. Эти объекты могут иметь переменные экземпляра и методы, как обычно.
Теперь, когда мы определили класс ошибок, мы можем фиксировать ошибки только из одного конкретного класса, а не из всех возможных исключений. Рекомендуется обрабатывать только известный набор ошибок, с которыми вы можете справиться. Это можно сделать, указав ограничение типа для ключевого слова rescue:
def half?(num)
half(num)
rescue error : OddNumberError
nil
end
Вы можете повторить несколько блоков rescue, чтобы зафиксировать и обработать несколько различных типов исключений. Единственная ситуация, в которой вы не можете быть разборчивы, – это встроенное восстановление, поскольку оно всегда будет обрабатывать и заменять все исключения.
Резюме
В этой главе вы узнали, как создавать классы и структуры, разобравшись в их различиях. Стало ясно, что каждое отдельное значение является объектом - даже сами классы являются объектами: объекты содержат данные, и ими можно манипулировать с помощью методов. Вы узнали, как наследовать и расширять классы, а также как создавать повторно используемые модули для организации вашего кода. Наконец, вы узнали об исключениях и о том, как использовать классы для создания ошибок пользовательского типа. Поскольку язык в значительной степени объектно-ориентирован, вы будете взаимодействовать с объектами практически в каждой строке кода. Знание того, как определять свои собственные классы, является важным навыком для написания программ на Crystal.
В следующей главе мы перейдем к решению более практических задач с использованием языка Crystal, написав несколько инструментов для интерфейса командной строки (CLI).
Часть 2: Обучение на практике – CLI
В этой части будет представлен первый проект Learn by Doing, в котором будет рассказано обо всем, что необходимо для создания CLI-приложения. Это включает в себя различные функции Crystal, такие как операции ввода-вывода, волокна и привязки C. В этой части также будут рассмотрены основы создания нового проекта Crystal.
Эта часть содержит следующие главы:
• Глава 4, изучение Crystal с помощью написания интерфейса командной строки
• Глава 5, Операции ввода/вывода
• Глава 6, Параллелизм
• Глава 7, Взаимодействие с C
4. Изучение Crystal с помощью написания интерфейса командной строки
Теперь, когда вы знакомы с основами Crystal, мы готовы применить эти навыки на практике. В этой части мы расскажем вам о создании интерфейса командной строки (CLI), в котором будут использованы концепции из Главы 1 "Введение в Crystal", а также некоторые новые.
Эта глава станет введением в суть данной части книги, в которой основное внимание будет уделено настройке проекта и первому этапу реализации интерфейса командной строки. Идея заключается в том, что в этой главе описывается первоначальная реализация, а затем в последующих главах она расширяется и улучшается.
Цель CLI – создать программу, позволяющую использовать данные YAML с jq, популярным CLI-приложением, которое позволяет разделять, фильтровать, отображать и преобразовывать структурированные данные JSON с помощью фильтра для описания этого процесса. Эта глава послужит отправной точкой нашего проекта, в которой будут рассмотрены следующие темы:
• Введение в проект
• Построение структуры проекта
• Написание базовой реализации
К концу этой главы вы сможете создавать свои собственные проекты Crystal, в том числе понимать, для чего используется каждый файл и папка в проекте. Вы также познакомитесь с тем, как работать с проектами, состоящими из нескольких файлов и папок. Оба эти элемента являются важными составляющими любого приложения Crystal.
Технические требования
Для выполнения кода, описанного в этой главе, вам понадобится следующее программное обеспечение:
• Работающая установка Crystal
• Рабочая установка jq
Инструкции по получению Crystal можно найти в Главе 1 «Введение в Crystal». настраивать. jq, скорее всего, можно установить с помощью менеджера пакетов в вашей системе, но можно также можно установить вручную, загрузив его с https://stedolan.github.io/jq/download.
Все примеры кода, использованные в этой главе, можно найти в папке Chapter 4 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/ tree/main/Chapter04.
Введение в проект
Прежде чем мы перейдем к нашему CLI-приложению, было бы полезно немного понять, как работает jq, поскольку он является основной частью желаемой функциональности нашего приложения. Как упоминалось ранее, jq позволяет создавать фильтры, которые используются для описания того, как следует преобразовать входные данные JSON.
Фильтр состоит из строки различных символов и символов, некоторые из которых имеют особое значение. Самый простой фильтр — ., также известный как фильтр идентификации. Этот фильтр оставляет входные данные неизмененными, что может быть полезно в тех случаях, когда вы просто хотите отформатировать входные данные, учитывая, что jq по умолчанию печатает весь вывод. Фильтр идентификации также представляет входные данные, проходящие через несколько фильтров. Подробнее об этом в ближайшее время.
jq включает в себя различные другие фильтры, целью которых является доступ к определенным частям входных данных или управление выполнением фильтра. Наиболее распространенными из них являются следующие:
• Индекс идентификатора объекта
• Индекс массива
• Запятая
• Pipe
Фильтр индекса идентификатора объекта позволяет получить доступ к значению по определенному ключу, предполагая, что входные данные являются объектом, и выдает ошибку, если это не так. Этот фильтр вернет значение null, если нужный ключ отсутствует в объекте. Например, использование фильтра .name для входных данных {"id":1,"name":"George"} приведет к получению выходного значения "George". Фильтр индекса массива работает во многом аналогично фильтру индекса идентификатора объекта, но для входных данных массива. Учитывая входные данные [1, 2, 3], использование фильтра .[1] даст выход 2.
Хотя первые два примера посвящены доступу к данным, фильтры «Запятая» и «Канал» предназначены для управления потоком данных через фильтр. Если несколько фильтров разделены запятой, входные данные передаются каждому фильтру независимо. Например, используя ранее полученный входной объект, фильтр .id, .name выдает выходные данные 1 и "George", каждое в отдельной строке. С другой стороны, канал передает выходные данные фильтра слева в качестве входных данных для фильтра справа. Опять же,