Brief: действия
Изменение состояния (<-, NEW, DELETE)
Оператор CHANGE пишет значение в изменяемое свойство, оператор NEW добавляет объект конкретного класса, операторы DELETE и CHANGECLASS удаляют объект или переводят его в другой класс:
[CHANGE] propertyId(expr1, ..., exprN) <- valueExpr [WHERE whereExpr]
NEW className WHERE whereExpr [TO propertyId(prm1, ..., prmN)]
NEW [alias =] className [AUTOSET] action
DELETE expr [WHERE whereExpr]
CHANGECLASS expr TO className [WHERE whereExpr]
Изменение пишется сразу по всем наборам аргументов, удовлетворяющим условию, одной операцией над множеством. Аналогия: UPDATE ... SET ... WHERE, а не присваивание переменной. При смене класса или удалении платформа обнуляет хранимые значения первичных свойств, в которых объект стал недопустим.
setDiscount () {
discount(Customer c) <- 15 WHERE totalOrders(c) > 100;
NEW o = Order { date(o) <- currentDate(); }
}
Вызов и последовательность
Действие двойственно свойству: свойство говорит, чему значение равно, действие — как оно меняется. Объявляется инструкцией ACTION:
name [caption] [(param1, ..., paramN)] { actionBody } [options]
Тело в фигурных скобках — последовательность: вложенные действия выполняются в порядке записи; внутри блока можно объявить свойства LOCAL, живущие только во время его выполнения. Вызов действия записывается именем с аргументами, [EXEC] actionId(expression1, ..., expressionN) [TO toProperty], либо подставляется прямо как значение. Аналогия: вызов процедуры.
Циклы (FOR, WHILE)
Оператор FOR выполняет тело по разу на каждый набор объектов, для которого условие не NULL; оператор WHILE пересчитывает условие на каждом шаге, поэтому изменения из тела учитываются:
FOR expression [ORDER [DESC] orderExpr1, ..., orderExprN]
[TOP topExpr] [OFFSET offsetExpr]
[NEW [alias =] className]
DO action
[ELSE alternativeAction]
WHILE expression [ORDER [DESC] orderExpr1, ..., orderExprN]
[NEW [alias =] className]
DO action
К циклу обращаются, когда тело действительно построчное — диалог, сообщение, внешний вызов. Механизмы — цикл и рекурсивный цикл.
createDetails (Order o) {
FOR in(Sku s) NEW d = OrderDetail DO {
order(d) <- o;
sku(d) <- s;
}
}
Ветвление (CASE, IF)
Ветвление вызывает действие, соответствующее выполнившемуся условию; условие выполнено, если его значение не NULL. В операторах IF ... THEN и CASE условие записывается явно, в операторе MULTI условие — соответствие аргументов вызова сигнатуре действия, то есть диспетчеризация по классу аргумента:
IF condition
THEN action
[ELSE alternativeAction]
CASE [exclusionType]
WHEN condition1 THEN action1
...
WHEN conditionN THEN actionN
[ELSE elseAction]
MULTI [exclusionType] action1, ..., actionN
message (Shape s) { MULTI { message[Square](s); }, { message[Circle](s); } }
Отложенный вариант — абстрактное действие ABSTRACT: базовый модуль объявляет точку расширения, реализации к ней добавляют другие модули (расширение действий).
Управление потоком
BREAKвыходит из ближайшего цикла,CONTINUEпереходит к следующей итерации,RETURN [выражение]выходит из ближайшего вызова действия с указанным значением как результатом.TRY action [CATCH catchAction] [FINALLY finallyAction]—CATCHпоглощает ошибку, давая доступ к ней черезmessageCaughtException[]иlsfStackTraceCaughtException[];FINALLYвыполняется в любом случае. Аналогия:try/catch/finally.NEWTHREAD action [dispatchClause]— выполнение в отдельном потоке, сразу или по расписанию (SCHEDULE: задержка и период).NEWEXECUTORвыбирает, куда отправить поток: в серверный пул, где тело работает в сессии изменений вызывающего кода, или в клиентское соединение (CLIENT), где оно получает собственную новую сессию в навигаторе этого соединения.
Действия на форме
SHOW— открытие формы в интерактивном представлении; переданные объекты становятся текущими.DIALOG— то же открытие как диалог ввода значения: каждый объект, помеченныйINPUTилиCHANGE, возвращает в блокDOсвое последнее текущее значение.ACTIVATE— активация формы, вкладки, свойства или набора объектов в группе объектов.EXPAND/COLLAPSE— разворачивание и сворачивание контейнера формы и узлов дерева объектов.MESSAGEиINPUT— сообщение и ввод значения без отдельной формы.
ACTIVATE FORM formName
ACTIVATE TAB formName.componentSelector
ACTIVATE PROPERTY formPropertyId
ACTIVATE [seekDirection] formObjectId = expr
ACTIVATE [seekDirection] formGroupObjectId [OBJECTS formObject1 = expr1, ..., formObjectK = exprK]