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

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

Если вам интересно, нет, нет способа волшебным образом получить значение из воздуха только потому, что у нас есть индекс переменной экземпляра и TypeNode типа, которому оно принадлежит. Для извлечения нам понадобится реальный экземпляр MyClass. Чтобы учесть это, нам нужно добавить в PropertyMetadata несколько дополнительных методов:

def value(obj : ClassType)

  {% begin %}

     obj.@{{ClassType.instance_vars[PropertyIdx].name.id}}

  {% end %}

end

def value(obj) i : NoReturn

    raise "BUG: Invoked default value method."

end

Другая хитрость, которая делает эту реализацию возможной, — это возможность прямого доступа к переменным экземпляра типа, даже если у них нет метода получения через синтаксис obj.@ivar_name. В предисловии к этому я скажу, что вам не следует использовать это часто, если вообще когда-либо, за исключением очень специфических случаев использования, таких как этот. Это антишаблон, и его следует избегать, когда это возможно. В 99% случаев вам следует вместо этого определить метод получения, чтобы вместо этого предоставить значение переменной экземпляра.

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

def value(obj : ClassType)

    obj.@name

end

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

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

my_class = MyClass.new

pp MyClass.metadata["name"].value my_class

Вы должны увидеть значение свойства name, напечатанное на вашем терминале, которое в данном случае будет "Jim". У этой реализации есть один недостаток. Тип значения, возвращаемого методом #value, будет состоять из объединения всех свойств, имеющих аннотацию данного типа. Например, typeof(name_value) вернет (String | Time), что в целом приводит к менее эффективному представлению памяти.

Этот шаблон отлично подходит для реализации мощных внутренних API, но его следует использовать с осторожностью, не использовать в «горячем» пути приложения и даже не публиковать публично.

Если вы помните Главу 9 «Создание веб-приложения с помощью Athena», где вы применяли аннотации ограничений проверки, компонент Validator Athena реализован с использованием этого шаблона, хотя и с несколько большей сложностью.

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

<p>Моделирование всего класса</p>

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

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

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

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

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

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

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

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

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

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