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

• Использование аннотаций для влияния на логику времени выполнения.

• Представление данных аннотаций/типов во время выполнения.

• Определение значения константы во время компиляции.

• Создание собственных ошибок времени компиляции.

К концу этой главы вы должны иметь более глубокое понимание метапрограммирования в Crystal. У вас также должны быть некоторые идеи о неочевидных вариантах использования метапрограммирования, которые позволят вам создавать уникальные решения проблем в вашем приложении.

<p>Технические требования</p>

Прежде чем мы углубимся в эту главу, в вашей системе должно быть установлено следующее:

• Рабочая установка Crystal.

Инструкции по настройке Crystal можно найти в Главе 1 «Введение в Crystal».

Все примеры кода, использованные в этой главе, можно найти в папке Chapter13 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter13.

<p>Использование аннотаций для влияния на логику времени выполнения</p>

Как мы узнали в Главе 11 «Введение в аннотации», аннотации — это отличный способ добавить дополнительные метаданные к различным функциям Crystal, таким как типы, переменные экземпляра и методы. Однако одним из их основных ограничений является то, что хранящиеся в них данные доступны только во время компиляции.

В некоторых случаях вам может потребоваться реализовать функцию с использованием аннотаций для настройки чего-либо, но логика, требующая этих данных, не может быть сгенерирована только с помощью макросов и должна выполняться во время выполнения. Например, предположим, что мы хотим иметь возможность печатать экземпляры объектов в различных форматах. Эта логика может использовать аннотации, чтобы отметить, какие переменные экземпляра следует предоставлять, а также настроить способ их форматирования. Высокоуровневый пример этого будет выглядеть так:

annotation Print; end

class MyClass

   include Printable

   @[Print]

   property name : String = "Jim"

   @[Print(format: "%F")]

   property created_at : Time = Time.utc

   @[Print(scale: 1)]

   property weight : Float32 = 56.789

end

MyClass.new.print

Результатом этого может быть следующее:

---

name: Jim

created_at: 2021-11-16

weight: 56.8

---

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

module Printable

  def print(printer)

    printer.start

      {% for ivar in @type.instance_vars.select(&.annotation Print) %}

        printer.ivar({{ivar.name.stringify}},

        @{{ivar.name.id}},

        {{ivar.annotation(Print).named_args.double_splat}})

      {% end %}

    printer.finish

  end

  def print(io : IO = STDOUT)

    print IOPrinter.new(io)

  end

end

Большая часть логики выполняется в методе #print(printer). Этот метод напечатает начальный шаблон, которым в данном случае являются три тире. Затем он использует макрос цикла for для перебора переменных экземпляра включающего типа. Переменные экземпляра фильтруются таким образом, что включаются только те, у которых есть аннотация Print. Затем для каждой из этих переменных вызывается метод #ivar на принтере с именем и значением переменной экземпляра, а также любых именованных аргументов, определенных в аннотации. Наконец, он печатает конечный образец, который также состоит из трех тире.

Для поддержки предоставления значений из аннотации мы также используем метод NamedTupleLiteral#double_splat вместе с Annotation#named_ args. Эта комбинация предоставит любые пары ключ/значение, определенные в аннотации, в качестве именованных аргументов для вызова метода.

Метод #print(io) служит основной точкой входа для печати экземпляра. Он позволяет предоставить пользовательский I/O, на который должны выводиться данные, но по умолчанию это STDOUT. I/O используется для создания другого типа, который фактически выполняет печать:

struct IOPrinter

  def initialize(@io : IO); end

  def start

    @io.puts "---"

  end

  def finish

    @io.puts "---"

    @io.puts

  end

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

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

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

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

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

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

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

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

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