Выражения сценариев
Обзор
Выражение – это заданная автором сценария последовательность арифметических или строковых действий, оперирующая константами, переменными и функциями от них, в том числе функциями с сайд-эффектами. Выражение используется для подстановки в качестве аргумента в значение компонентов сценария.
Результат выражения может иметь тип сроки или числа. Даты также представляются в виде строк в формате RFC3339.
Значения типа bool
на выходе автоматически преобразуются к строке true
или false
. С помощью функции ifelse(bool,any,any)
результат можно привести к другим значениям, например числам 0
или 1
.
Чтобы в качестве аргумента выражения использовать значение переменной, следует указать ее имя в квадратных скобках.
Для явного указания строки следует заключать текст в кавычки. В противном случае, сначала будут вычислены все арифметические комбинации, доступные для расчета. В приведенных примерах 2.3 и 2.4 результат будет разный, то есть началом результирующей строки примера 2.3 будет являться символ «5», а примера 2.4 – символы «23».
Разбиение на строки производится с помощью функции endline()
.
Примеры числовых выражений:
-
(1.1)
[переменная_число_1] + 1
-
(1.2)
2 ^ [переменная_число_2] * ( Log10 ( [переменная_число_3] ) + 2 )
-
(1.3)
sin ( len ( [переменная_строка_1] ) )
Примеры строковых выражений:
-
(2.1)
[переменная_строка_1] + [переменная_строка_2]
-
(2.2)
"Кусок текста" + [переменная_строка_1]
-
(2.3)
2 + 3 + [переменная_строка_1]
-
(2.4)
"2" + "3" + [переменная_строка_1]
-
(2.5)
SubStr ( [переменная_строка], 1, Length ( [переменная_строка] ) - 1 )
-
(2.6)
If ( num([a]) > 5, "больше", "меньше")
Операции
Функция | Тип значения | Описание |
---|---|---|
|
|
Если аргументы могут быть приведены к числам, то результатом является сумма двух чисел. Иначе аргументы они приводятся к строке и сцепляются. |
|
|
Приводит аргументы к строке и сцепляет их. |
|
|
Если аргументы могут быть приведены к числам, то результатом является их разность. Иначе операция завершается с ошибкой. |
|
|
Если аргументы могут быть приведены к числам, то результатом является их произведение. Иначе операция завершается с ошибкой. |
|
|
Если аргументы могут быть приведены к числам, то результатом является их частное. Иначе операция завершается с ошибкой. |
|
|
Если аргументы могут быть приведены к целым числам, то результатом является целая часть их частного. Иначе операция завершается с ошибкой. |
|
|
Если аргументы могут быть приведены к целым числам, то результатом является остаток от деления. Иначе операция завершается с ошибкой. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Равенство. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Неравенство. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Больше. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Больше или равно. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Меньше. |
|
|
Приводит значения аргументов к одному типу и сравнивает их. Меньше или равно. |
Экранирование JSON
При работе с JSON, собирая строковое значение, необходимо использовать конкатенацию строк и экранирование двойных кавычек.
"{ \"a\": null, \"b\": 1, \"c\": \"value\", \"d\": false, \"e\": \"" + str([name]) + "\", \"f\": \"" + str(num([a]) + num([res]) + 10) + "\", \"g\": [ \"g1\", \"g2\", \"g3\" ], \"h\": { \"h1\": 1, \"h2\": \"value\", \"h3\": [1, 2, 3], \"h4\": { \"h41\": \"" + str(nowtick()) + "\", \"h42\": {\"x\": \"value\"} } } }"
В ряде случаев удобнее собирать JSON в виде шаблона - компактнее и меньше символов экранирования. При этом из выражения в шаблон и обратно можно в любой момент переключиться, если текущее содержание поля корректно.
Шаблоны
Приложение редактора сценариев позволяет задавать выражения с помощью шаблонов.
Шаблон представляет собой строку, в которую в фигурных скобках входят вычислимые выражения. При этом переход между вкладками задания шаблона и задания выражения производит автоматическое взаимное преобразование.
"abc." + str([var]) + ".def" + endline() + replace([var],";",".") + substring([var2],3,5) + "zzz"
abc.{str([var])}.def {replace([var1],";",".") + substring([var2],3,5)}zzz
В шаблонах, содержащих фигурные скобки в самих значениях (например, JSON), следует их экранировать с помощью обратного слэша.
\{ "a": null, "b": 1, "c": "value", "d": false, "e": "{str([name])}", "f": "{str(num([a]) + num([res]) + 10)}", "g": [ "g1", "g2", "g3" ], "h": \{ "h1": 1, "h2": "value", "h3": [1, 2, 3], "h4": \{ "h41": "{str(nowtick())}", "h42": \{"x": "value"\} \} \} \}
Синтаксис erlang
Выражения интерпретируются в качестве кода на языке erlang. Перед интерпретацией производится предварительная трансляция для поддержки встроенных функций, подстановки переменных.
Поддерживаются функции высоких порядков, вызовы системных модулей, а также модулей-плагинов, добавленных в систему с помощью патчей.
ВАЖНО: значения в одинарных кавычках задают атомы (кроме случаев, когда одинарные кавычки используются в теле строк, бинарных выражений или комментариев). Атомы - это неудаляемые константы вплоть до перезапуска ноды. Поэтому при формировании строк лучше использовать двойные кавычки.
Решая сложную алгоритмическую задачу в сценарии, предполагающую чистую функцию, может быть полезным переведение ее в код выражения на erlang. Ниже приводится пример выражения на erlang.
% io:format("DEBUG. a~n",[]), Ctx = jsx:decode([context],[return_maps]), io:format("DEBUG. b~n",[]), P = jsx:decode([param],[return_maps]), io:format("DEBUG. c~n",[]), % Map2 = case P of Map when is_map(Map) -> maps:merge(Ctx,Map); [<<"merge">>,Map] when is_map(Map) -> r_env_utils:merge_maps(Map,Ctx,2); [<<"increment">>,Fld] when is_binary(Fld) -> Ctx#{Fld => r_env_utils:to_int(maps:get(Fld,Ctx,0),0) + 1}; [<<"increment">>,Map] when is_map(Map) -> io:format("increment ~120tp~n",[Map]), lists:foldl(fun(Fld,Acc) -> Acc#{Fld => r_env_utils:to_int(maps:get(Fld,Acc,0),0) + 1} end, Ctx, maps:keys(Map)); [<<"append">>,Map] when is_map(Map) -> Map1 = r_env_utils:merge_maps(Map,Ctx,2), maps:fold(fun(K,V,Acc) -> case maps:get(K,Ctx,undefined) of [_|_]=L when is_list(V) -> Acc#{K => L++V}; _ -> Acc end end, Map1, Map) end, io:format("DEBUG. d~n",[]), % jsx:encode(Map2, [{space,2},{indent,1}])
Конкретно этот пример осуществляет функцию изменения контекста в переменной 'context' на основе управляющей команды из переменной 'param'. Формат значений того и другого установлен самим сценарием и поддерживается в выражении.
Выражение использует модули самой платформы erlang (maps, io), модуль подключенной зависимости по работе с JSON (jsx), модуль коммуникацинной платформы (r_env_utils), а также функции основного модуля erlang (is_list).
Выражение исполняясь выводит в консоль ноды отладочную информацию.