Проект DeclarativeCOS — крик души по теме программирования на COS.
Цель проекта — обратить внимание сообщества к улучшению внутреннего ядра COS.
Идея проекта — поддержка лаконичного синтаксиса при работе с циклами и коллекциями.

Итак, что же лаконичного я придумал? Добро пожаловать в примеры!
Примеры
Ключевой концепт проекта — декларативный подход. Нужно указать ЧТО нужно использовать и КАК.
Лично мне всегда не хватало простого оператора/команды/заклинания в терминале COS для того, чтобы вывести коллекцию на экран в том виде, в котором тебе это хочется. А теперь есть две приятные штуки: zforeach и $zjoin!
>s words = ##class(%ListOfDataTypes).%New() >d words.Insert(“Hello”) >d words.Insert(“World!”) >zforeach $zbind(words, “io:println”) Hello World!
Здесь стоит рассказать подробнее о функции $zbind. Начать следует с того, что COS можно расширять своими командами и функциями, о чем можно подробно написано в соответствующей документации и статье на портале сообщества разработчиков.
Эта функция создает экземпляр класса Binder. Его задача — связать коллекцию и функцию, которую нужно применить к каждому элементу коллекции. В данном случае, используется стандартная функция с именем “io:println” из DeclarativeCOS, которая для заданного значения value выполняет простую команду:
>w value,!
Команда zforeach работает с экземпляром класса Binder, последовательно проходя по коллекции и применяя функцию к каждому ее элементу.
$zjoin — создает строку из коллекции, объединяя ее элементы между которыми добавляется указанный разделитель.
>s numbers = ##class(%ListOfDataTypes).%New() >d numbers.Insert(“04”) >d numbers.Insert(“03”) >d numbers.Inset(“2017”) >w $zjoin(numbers, “ / ”) 04 / 03 / 2017
$zmap — создает новую коллекцию из элементов исходной коллекции к каждому элементу которой применена указанная функция.
>set numbers = ##class(%ListOfDataTypes).%New() >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >write "[" _ $zjoin(numbers, ", ") _ "]" [82, 12, 27] >set hexNumbers = $zmap(numbers, "examples:toHex") >write "[" _ $zjoin(hexNumbers, ", ") _ “]” [52, C, 1B]
$zfind — находит первый элемент коллекции, на котором указанная функция возвращает $$$YES. Иначе возвращает null-строку.
>set numbers = ##class(%ListOfDataTypes).%New() >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >set primeNumber = $zfind(numbers, "examples:isPrime") >write "[" _ $zjoin(numbers, ", ") _ "]" [69, 41, 68] >write "Prime number: " _ $select(primeNumber="":"<not found>", 1:primeNumber) Prime number: 41
$zfilter — создает новую коллекцию на основе исходной коллекции, но взяв только те элементы, на которых указанная функция возвращает $$$YES. Если таких элементов нет, то возвращает пустую коллекцию.
>set numbers = ##class(%ListOfDataTypes).%New() >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >set filteredNumbers = $zfilter(numbers, "examples:isOdd") >write "[" _ $zjoin(numbers, ", ") _ "]" [22, 71, 31] >write "[" _ $zjoin(filteredNumbers, ", ") _ "]" [71, 31]
$zexists — проверяет, что в коллекции есть хотя бы один элемент, на котором указанная функция возвращает $$$YES.
>set numbers = ##class(%ListOfDataTypes).%New() >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >do numbers.Insert($random(100)) >set hasEvenNumbers = $zexists(numbers, "examples:isEven") >write "[" _ $zjoin(numbers, ", ") _ "]" [51, 56, 53] >write "Collection has" _ $case(hasEvenNumbers, 1:" ", 0:" no ") _ "even numbers" Collection has even numbers
$zcount — подсчитать количество элементов в коллекции, на которых указанная функция возвращает $$$YES.
>set numbers = ##class(%ListOfDataTypes).%New() >do numbers.Insert($random(1000)) >do numbers.Insert($random(1000)) >do numbers.Insert($random(1000)) >set palindromicNumbersCount = $zcount(numbers, "examples:isPalindromic") >write "[" _ $zjoin(numbers, ", ") _ "]" [715, 202, 898] >write "Count of palindromic numbers: " _ palindromicNumbersCount Count of palindromic numbers: 2
Установка
Для установки DeclarativeCOS достаточно скачать с официального GitHub репозитория проекта два файла:
- install.base.xml — просто классы. Без z-функций.
- install.advanced.xml — %ZLANG рутины, которые добавляют z-функции.
Как пользоваться
- Унаследовать класс от DeclarativeCOS.DeclarativeProvider.
- Реализовать метод класса.
- Пометить этот метод аннотацией @Declarative.
- Использовать z-функции DeclarativeCOS.
- Почувствовать счастье.
Подробная инструкция.
Class MyPackage.IO extends DeclarativeProvider { }
Class MyPackage.IO extends DeclarativeProvider { ClassMethod println(value As %String) { w value,! } }
Class MyPackage.IO extends DeclarativeProvider { /// @Declarative("myIO:myPrintln") ClassMethod println(value As %String) { w value,! } }
>s words = ##class(%Library.ListOfDataTypes).%New() >d words.Insert("Welcome") >d words.Insert("to") >d words.Insert("DeclarativeCOS!") >zforeach $zbind(words, "myIO:println")
Welcome to DeclarativeCOS!
Как это работает
Проект DeclarativeCOS использует глобал ^DeclarativeCOS для того чтобы сохранить информацию о методах, помеченных аннотацией @Declarative(declarativeName).
Каждая такой метод сохраняется в глобал в следующем виде:
set ^DeclarativeCOS(declarativeName) = $lb(className, classMethod)
Например, для функции io:println:
set ^DeclarativeCOS(“io:println”) = $lb(“DeclarativeCOS.IO”, “println”)
Каждый раз, когда используется функция io:println происходит поиск по глобалу, а потом функция $classmethod сделает вызов исходного метода (DeclarativeCOS.IO # println) на заданном значении.
Заключение
DeclarativeCOS это вклад в новый Caché ObjectScript. В тот самый язык, который действительно помогает своим разработчикам писать программы быстро, лаконично, просто и надежно. Добро пожаловать в критику, поддержку и мнения в комментарии под этим постом!)
ссылка на оригинал статьи https://habrahabr.ru/post/327016/
Добавить комментарий