Читаем Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI полностью

Два основных улучшения заключаются в том, что любой вывод ошибок, возникающий во время работы jq, должен выводиться в STDERR и что программа должна завершиться раньше, если jq не выполнился успешно.

Эти два улучшения позволяют пользователю понять, что пошло не так, и предотвращают дальнейшее выполнение приложения, которое в противном случае привело бы к попытке преобразовать сообщение об ошибке в YAML.

<p>Поддержка других IO</p>

В последнем разделе мы уже внесли немало улучшений: нам больше не нужно жестко кодировать входные данные, и мы лучше справляемся с ошибками, исходящими от jq. Но помните, как мы также хотели поддержать использование нашего приложения в контексте библиотеки? Как кто-то будет обрабатывать тело ответа HTTP и выводить его в файл, если наш процессор тесно связан с концепцией терминала?

В этом разделе мы собираемся устранить этот недостаток, снова проведя рефакторинг, чтобы разрешить любой тип IO, а не только типы IO на основе терминала.

Первым шагом в этом является повторное введение аргументов в Processor#process: один для входных аргументов, входной IO, выходной IO и IO ошибок. В конечном итоге это будет выглядеть так:

class Transform::Processor

  def process(input_args : Array(String), input : IO,

    output : IO, error : IO) : Nil

    filter = input_args.shift

    input = input.gets_to_end

    output_data = String.build do |str|

      run = Process.run(

        "jq",

        [filter],

        input: IO::Memory.new(

          Transform::YAML.deserialize input

        ),

        output: str,

        error: error

      )

      exit 1 unless run.success?

    End

    output.puts Transform::YAML.serialize output_data

  end

end

Затем мы, конечно, должны обновить связанные константы, добавив в них новые переменные-аргументы. Как упоминалось ранее, вывод этого метода непосредственно в STDOUT делал его не таким гибким, как тогда, когда он просто возвращал окончательные преобразованные данные. Однако теперь, когда он поддерживает любой тип IO в качестве вывода, кто-то может легко использовать String.build для получения строки преобразованных данных. Далее нам нужно будет обновить нашу логику преобразования, чтобы она также основывалась на IO.

Откройте src/yaml.cr и обновите первый аргумент, чтобы он принимал IO, а также добавьте еще один аргумент IO, который будет представлять выходные данные. Оба метода .parse поддерживают String | IO входы, поэтому нам там ничего особенного делать не нужно. Методы #to_* также имеют перегрузку на основе IO, которой мы передадим новый выходной аргумент. Наконец, поскольку этот метод больше не будет возвращать преобразованные данные в виде строки, мы можем обновить тип возвращаемого значения на Nil. В конечном итоге это должно выглядеть следующим образом:

require "yaml"

require "json"

module Transform::YAML

  def self.deserialize(input : IO, output : IO) : Nil

    ::YAML.parse(input).to_json output

  end

  def self.serialize(input : IO, output : IO) : Nil

    JSON.parse(input).to_yaml output

  end

end

Поскольку мы добавили второй аргумент, нам, конечно, также потребуется обновить процессор для передачи второго аргумента. Аналогичным образом, поскольку сейчас мы работаем исключительно с операциями IO, нам нужно будет реализовать новый способ хранения/перемещения данных. Мы можем решить обе эти задачи, используя объекты IO::Memory для хранения преобразованных данных. Кроме того, поскольку они сами относятся к типу IO, мы можем передавать их непосредственно в качестве входных данных в jq.

Конечный результат этого рефакторинга следующий:

class Transform::Processor

  def process(input_args : Array(String), input : IO,

    output : IO, error : IO) : Nil

    filter = input_args.shift

    input_buffer = IO::Memory.new

    output_buffer = IO::Memory.new

    Transform::YAML.deserialize input, input_buffer

    input_buffer.rewind

    run = Process.run(

      "jq",

      [filter],

      input: input_buffer,

      output: output_buffer,

      error: error

    )

    exit 1 unless run.success?

    output_buffer.rewind

    Transform::YAML.serialize output_buffer, output

  end

end

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных