20 октября 2011 г.

Lipa в действии

Как я и обещал, пишу статью о возможностях Lipa. Пока я готовил материал и пробовал его , обнаружил несколько ошибок, которые в тот же момент и исправил. На текущий момент версия библиотеки 0.2.2 и, то что буду показывать, работает на Ruby 1.9.2. И так...


Постановка задачи

С подачи анонимного комментатора... Имеем склад товаров(store). Товары(unit) разбиты на категории(category) и имеют такие атрибуты, как: количество товара на складе(count), номер производителя (part_number), стоимость(cost) и марка(label). Категории могут включать в себя другие категории и уровень вложенности неограничен.

Простое дерево

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


Шаблоны

Наверно, не впечатлило)) Конечно такую же структуру можно было описать и с помощью например YAML и не изобретать велосипед. Да и где тут DSL? А DSL мы обеспечим с помощью шаблонов(kind). Опишем шаблон для категории и товара:


Это уже выглядит получше. В шаблоне можно задать атрибуты по умолчанию, я покажу это в следующем примере. Что бы Lipa поняла для чего описан шаблон надо записать в  атрибут :for имя метода инициализации узла, в нашем случае :node. Еще обратите внимание на метод with, он задает атрибуты узлам внутри своего параметра блока, но никак не влияет на структуру дерева. Может быть полезно, если у вас много узлов с одинаковыми атрибутами, но отдельный шаблон создавать для них неудобно. В моем примере мы задали марку Sony для двух узлом tv_1 и tv_2.

Вычисления

Lipa умеет не только описывать данные в DSL стиле, но и позволяет добавлять в структуру код для обработки данных. Сделать это можно, описав атрибут, как Proc объект. Ниже пример добавления счётчиков количества(unit_count) и общей стоимости(total_cost) товаров в категории:


Описывая Proc объекты, мы можем обращаться к любым атрибутам из его тела. Хорошей практикой будет задать значения по умолчанию для атрибутов, которые участвуют в вычислениях, для того, что бы если вы вдруг забыли в экземпляре шаблона его описать, Ваш код не завершился с ошибкой. Таким образом можно обеспечивать фильтрацию данных, анализ и т.к.. С возможность подключения кода к дереву объектов Lipa становиться не просто библиотекой для описания данных в DSL стиле, но патерном проектирования программ работающих с древовидными данными. Так же Lipa можно расширять с помощью своих классов потомков от Lipa::Node.., но я позже подробнее об этом расскажу.

Чем Lipa не является!

Что бы избежать заблуждений, скажу пару слов что в Lipa не делает и не будет делать.
  1. Претендовать на СУБД. Lipa не создана, для хранения больших массивов данных, быстрой выборки и манипуляции данными. Хоть и API Lipa позволяет добавлять узлы "налету", но сохранить их где либо она не сможет и после перезапуска изменения будут утеряны;
  2. Повторять функционал ORM. Хоть шаблоны узлов и есть модели в понятия ORM. Lipa не будет иметь валидации и коннекторов к БД. Структура в виде хеша храниться в памяти и там умирает после остановки программы.
  3. Работать там, где используют общепризнанные форматы данных(XML,JSON). Lipa создан для простого ручного ввода данных, а не для хранения и передачи данных м\у программами. 
 Во всех остальных случаях, когда YAML мало, а написание своего DSL стандартными средствами того не стоит - Lipa хорошее решение!

Комментариев нет:

Отправить комментарий