- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих
Шрифт:
Интервал:
Закладка:
Хотя то, что мы сделали в этой главе, может показаться довольно простым, важно помнить, что эти концепции являются общими для каждого будущего проекта Crystal, который вы будете создавать. Правильный дизайн приложения, как с точки зрения организационной структуры, так и с точки зрения самого кода, является важной частью разработки удобочитаемых, тестируемых и сопровождаемых приложений.
5. Операции ввода/вывода
В этой главе будет подробно рассмотрено CLI-приложение, о котором говорилось в предыдущей главе, с акцентом на операции ввода/вывода (IO). В ней будут рассмотрены следующие темы:
• Поддержка терминального ввода-вывода, такого как STDIN/STDOUT/STDERR
• Поддержка дополнительного ввода-вывода
• Тестирование производительности
• Объяснение поведения ввода-вывода
К концу этой главы у вас должно быть общее представление об операциях ввода-вывода, в том числе о том, как их использовать и как они себя ведут. С помощью этих концепций вы сможете создавать интерактивные, эффективные потоковые алгоритмы, которые могут быть использованы в различных приложениях. Знание того, как работает IO, также поможет вам понять более сложные концепции, которые будут рассмотрены в следующих главах, таких как Глава 6 "Параллелизм".
Технические требования
Для выполнения кода, описанного в этой главе, вам потребуется следующее программное обеспечение:
• Рабочая установка Crystal
• Рабочая установка jq
• Средство измерения использования памяти, например https://man7.org/linux/man-pages/man1/time.1.html с параметром -v
Инструкции по настройке Crystal приведены в Главе 1 "Введение в Crystal". Скорее всего, jq можно установить с помощью менеджера пакетов в вашей системе, но его также можно установить вручную, загрузив с сайта https://stedolan.github.io/jq/download.
Все примеры кода, использованные в этой главе, можно найти в папке Chapter 5 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter05.
Поддерживающий терминальный ввод/вывод
В предыдущей главе мы остановились на нашем типе процессора, имеющем метод def process(input : String) : String, который преобразует входную строку, обрабатывает ее с помощью jq, а затем преобразует и возвращает выходные данные. Затем мы вызываем этот метод со статическим вводом. Однако CLI-приложение не очень полезно, если его нужно перекомпилировать каждый раз, когда вы хотите изменить входные данные.
Более правильный способ справиться с этим - использовать терминальный ввод-вывод, а именно Standard In(STDIN), Standard Out (STDOUT) и Standard Error (STDERR). Это позволит нам использовать данные, выводить данные и выводить ошибки соответственно. Фактически, вы уже используете стандартный вывод, даже не подозревая об этом! Метод Crystal puts записывает переданное ему содержимое в стандартный вывод, за которым следует перевод строки. Тип STDOUT наследуется от абстрактного типа ввода-вывода, который также определяет метод puts для экземпляра ввода-вывода. В принципе, это позволяет вам делать то же самое, что и puts верхнего уровня, но для любого ввода-вывода. Например, обратите внимание, что эти два варианта puts дают один и тот же результат:
puts "Hello!" # => Hello!
STDOUT.puts "Hello!" # => Hello!
Но подождите, что такое IO? Технически в Crystal IO — это все, что наследуется от абстрактного типа IO.
Однако на практике ввод/вывод обычно представляет собой что-то, что может записывать и/или считывать данные, например файлы или тела HTTP-запроса/ответа. IO также обычно реализуется таким образом, что не все читаемые/записываемые данные должны находиться в памяти одновременно, чтобы поддерживать «потоковую передачу» данных. Пользовательский IO также может быть определен для более специализированных случаев использования.
В нашем контексте типы STDIN, STDOUT и STDERR фактически являются экземплярами IO::FileDescriptor.
Crystal предоставляет некоторые полезные типы IO, которые мы уже использовали. Помните, как мы также использовали IO::Memory как средство передачи преобразованных входных данных в jq? Или как мы использовали String.build для создания строки данных после того, как jq преобразовал ее? IO::Memory — это реализация IO, которая хранит записанные данные в памяти приложения, а не во внешнем хранилище, таком как файл. Метод String.build выдает IO, в который можно записать данные, а затем возвращает записанное содержимое в виде строки. Полученный IO можно рассматривать как оптимизированную версию IO::Memory. Пример этого в действии будет выглядеть так:
io = IO::Memory.new
io << "Hello"
io << " " << "World!"
puts io # => Hello World!
string = String.build do |io|
io << "Goodbye"
io << " " << "World"
end
puts string # => Goodbye World!
Стандартная библиотека Crystal также включает в себя несколько примесей, которые можно использовать для улучшения поведения IO. Например, модуль IO::Buffered можно включить в тип IO, чтобы повысить производительность за счет добавления буферизации ввода/вывода к типу IO Другими словами, вы можете сделать так, чтобы данные не записывались немедленно в базовый IO, если это тяжелый процесс. Файл является примером буферизованного IO.
Crystal также предоставляет некоторые дополнительные специализированные типы ввода-вывода, которые можно использовать в качестве строительных блоков для создания других типов IO. Некоторые из них, на которые стоит обратить внимание, включают следующее:
• Delimited — IO, который оборачивает другой IO, считывая только до начала указанный разделитель. Может быть полезно для экспорта только части потока клиенту.
• Hexdump — IO, который печатает шестнадцатеричный дамп всех переданных данных. Может быть полезно для отладки двоичных протоколов, чтобы лучше понять, когда и как данные отправляются/получаются.
• Sized — IO, который оборачивает другой ввод-вывод, устанавливая ограничение на количество байтов, которые можно прочитать.
Полный список см. в документации API: https://crystal-lang.org/api/IO.html.
Теперь, когда мы познакомились с IO, давайте вернемся к обновлению нашего CLI, чтобы лучше использовать ввод-вывод на основе терминала. Планируется обновить src/transform_cli.cr для чтения непосредственно из STDIN и вывода непосредственно в STDOUT. Это также позволит нам устранить необходимость в константе INPUT_DATA. Теперь файл выглядит так:
require "./transform"
STDOUT.puts Transform::Processor.new.process STDIN.gets_to_end
Главное, что изменилось, это то, что мы заменили константу INPUT_DATA на STDIN. get_to_end.