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

Чтобы это работало, вам нужно иметь возможность перебирать свойства и создавать хэш или массив внутри конструктора другого типа. Несмотря на то, что существует ограничение на чтение переменных экземпляра типа, оно не означает, что это должен быть метод внутри самого типа. Учитывая, что конструктор — это всего лишь метод, который возвращает self, это не будет проблемой. Несмотря на это, нам все равно нужна ссылка на TypeNode интересующего нас типа.

Поскольку макросы имеют доступ к общей информации, даже в контексте метода мы можем заставить этот тип ClassMetadata принимать аргумент универсального типа, чтобы передать ссылку на TypeNode. Кроме того, мы могли бы продолжать передавать общий тип другим типам/методам, которым он нужен.

Например, используя тот же тип PropertyMetadata, что и в последнем разделе:

annotation Metadata; end

annotation ClassConfig; end

class ClassMetadata(T)

  def initialize

    {{@type}}

    {% begin %}

      @property_metadata = {

        {% for ivar, idx in T.instance_vars.select &.

          annotation Metadata %}

          {{ivar.name.stringify}} => (

            PropertyMetadata({{@type}}, {{ivar.type.resolve}},

              {{idx}}).new({{ivar.name.stringify}},

                {{ivar.annotation(Metadata).named_args

                  .double_splat}})

          ),

        {% end %}

      } of String => MetadataBase

      @name = {{(ann = T.annotation(ClassConfig)) ?

        ann[:name] : T.name.stringify}}

    {% end %}

  end

  getter property_metadata : Hash(String, MetadataBase)

  getter name : String

end

Модуль Metadatatable теперь выглядит так:

module Metadatable

  macro included

  class_getter metadata : ClassMetadata(self)

     { ClassMetadata(self).new }

  end

end

Большая часть логики такая же, как и в предыдущем примере, за исключением того, что вместо прямого возврата хеша метод .metadata теперь возвращает экземпляр ClassMetadata, который предоставляет хеш. В этом примере мы также представили еще одну аннотацию, чтобы продемонстрировать, как предоставлять данные, когда аннотацию можно применить к самому классу, например настройку имени с помощью @[ClassConfig(name: "MySpecialName")].

В следующем разделе мы рассмотрим, как можно использовать макросы и константы вместе для регистрации вещей, которые можно будет использовать/перебирать в более поздний момент времени.

<p>Определение значения константы во время компиляции</p>

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

С появлением аннотаций этот шаблон уже не так полезен, как раньше. Тем не менее, это все равно может быть полезно, если вы хотите предоставить пользователю возможность влиять на некоторые аспекты вашей макрологики, и нет места для применения аннотации. Одним из основных преимуществ этого подхода является то, что его можно вызвать в любом месте исходного кода и при этом применить, в отличие от аннотаций, которые необходимо применять к связанному элементу.

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

MODELS = [] of ModelBase.class

macro register_model(type)

{% MODELS << type.resolve %}

end

abstract class ModelBase

end

class Cat < ModelBase

end

class Dog < ModelBase

end

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

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

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

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

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

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

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

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

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