Private KeeperPrivate Keeper
in-Line Kit

Скрипт-бокс

Многострочный сценарий, присваивание, условия, цикл FOR, критическая секция и итог выполнения.

Скрипт-бокс выполняет команды in-Line последовательно, строка за строкой. В нём можно присваивать значения, проверять условия, повторять блоки, изменять результат запуска и подключать заранее сохранённые фрагменты кода.

Как выполняются строки

Интерпретатор различает обычную команду, условный блок, цикл и служебную границу по началу строки. Поэтому положение команды и закрывающая строка являются частью синтаксиса.

Строка

|PARS|[1] = Ready выполняется один раз в текущем месте сценария.

Блок

|| или #FOR начинает последовательность вложенных строк.

Граница

||END, #ENDFOR или #endScript явно завершает соответствующую конструкцию.

Скрипт-бокс выполняется только при хорошем ответе и в самом конце обработки, перед выводом журнала. Не размещайте в нём действие, которое должно произойти до запроса или до получения результата парсера.

Многострочный код

#beginScript начинает многострочный блок, а #endScript завершает его. Переводы строк внутри присваиваемого значения сохраняются.

#beginScript
|PARS|[1] = test
message
#endScript

После выполнения первый парсер содержит две строки:

test
message
Работает

Начальная и конечная метки находятся на отдельных строках и образуют одну пару.

Ошибка

Без #endScript многострочный блок не имеет явной границы, поэтому следующую команду нельзя надёжно отделить от присваиваемого текста.

Присваивание

Обычный знак = изменяет значение слева. Это другой синтаксис, чем логический оператор равенства |=|.

|PARS|[1] = |PARS|[1]Test

Если первый парсер содержал Value, после команды он содержит ValueTest: правая часть сначала вычисляется из прежнего значения, затем результат записывается слева.

Присвоить

|DV|[Status] = Ready записывает Ready в существующую динамическую переменную.

Сравнить

|DV|[Status]|=|Ready возвращает истину или ложь и само значение не меняет.

Работает

Слева находится изменяемый парсер, динамическая переменная или другая поддерживаемая цель присваивания.

Ошибка

Запись Ready = |DV|[Status] пытается изменить постоянный текст, а не состояние проекта.

Комментарии

Строка, которая начинается с //, пропускается интерпретатором.

// Следующая команда отмечает успешную подготовку данных
|DV|[Status] = Ready
Работает

// временно не выполняем эту строку начинается со знака комментария.

Ошибка

|DV|[Status] = Ready // комментарий не является строкой комментария: // находится после команды.

Линейные условные блоки

Строка ||условие начинает блок, который выполняется только при истинном условии. Строка ||END завершает этот блок.

|||PARS|[1]|>|2
|PARS|[1] = |PARS|[1] руб.
|PARS|[2] = |PARS|[2] руб.
||END

Если первый парсер больше 2, суффикс руб. добавляется к обоим парсерам. Если условие ложно, обе строки пропускаются.

Работает

||END стоит после последней условной строки, поэтому границы блока видны однозначно.

Ошибка

Если ||END не указан, условию подчиняется только первая следующая строка; остальные строки выполняются независимо.

Линейные блоки можно вкладывать в цикл #FOR, а цикл — в линейный блок. Каждую конструкцию закрывает собственная команда.

Цикл FOR

#FOR повторяет вложенные строки по целому диапазону. Счётчиком служит заранее созданная динамическая переменная.

#FOR |DV|[index] = начало|TO|конец
команды
#ENDFOR
  • |TO| идёт по возрастанию;
  • |DOWNTO| идёт по убыванию;
  • начальная и конечная границы входят в диапазон;
  • обе границы вычисляются один раз перед началом цикла;
  • #ENDFOR завершает текущий цикл;
  • циклы можно вкладывать друг в друга;
  • глубина вложенности и общее количество повторов ограничены, чтобы ошибочный сценарий не выполнялся бесконечно.

До выполнения создайте динамическую переменную счётчика, например index, и все переменные, в которые цикл будет записывать результат. #FOR меняет их значения, но не создаёт их описание в проекте.

Сбор всех результатов

|DV|[index] = 0
|DV|[result] =
#FOR |DV|[index] = 1|TO||REGEXCOUNT|[1]
|DV|[result] = |DV|[result]|REGEXCYCLE|[|DV|[index]]
#ENDFOR

Цикл последовательно добавляет в result значения |REGEXCYCLE|[1], |REGEXCYCLE|[2] и далее до |REGEXCOUNT|[1] включительно.

Обратный порядок

|DV|[index] = 0
|DV|[result] =
#FOR |DV|[index] = 3|DOWNTO|1
|DV|[result] = |DV|[result]|DV|[index],
#ENDFOR

result получает 3,2,1,.

Работает

1|TO|3 и 3|DOWNTO|1 явно задают направление и выполняют по три итерации.

Ошибка

Цикл без #ENDFOR не имеет границы; счётчик, которого нет среди динамических переменных проекта, не может хранить текущую итерацию.

BREAK и CONTINUE

#CONTINUE переходит к следующему значению ближайшего цикла. #BREAK немедленно завершает ближайший цикл.

|DV|[index] = 0
|DV|[result] =
#FOR |DV|[index] = 1|TO|10
|||DV|[index]|=|3
#CONTINUE
||END
|||DV|[index]|=|7
#BREAK
||END
|DV|[result] = |DV|[result]|DV|[index],
#ENDFOR

result получает 1,2,4,5,6,: значение 3 пропускается, а перед добавлением 7 цикл завершается.

Работает

Каждая управляющая команда находится внутри #FOR ... #ENDFOR и относится к ближайшему циклу.

Ошибка

#BREAK или #CONTINUE вне цикла не имеет ближайшего цикла, которым можно управлять.

Критическая секция

|SYNCHOLE| = enter входит в критическую секцию, а |SYNCHOLE| = leave выходит из неё.

|SYNCHOLE| = enter
|DV|[SharedCount] = (|MATH||DV|[SharedCount]+1|MATH|)
|SYNCHOLE| = leave

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

Работает

Каждому enter соответствует leave, а защищённый участок остаётся коротким.

Ошибка

Выход до общей записи или отсутствие leave разрушает защиту и может задержать другие потоки.

Результат выполнения

|CONCLUSION| устанавливает итог текущего запуска.

0

Плохой результат.

1

Хороший результат.

3

Капча или блокировка.

99

Данные не подходят под настройки.

|CONCLUSION| = 0

Эта команда устанавливает плохой результат. Используйте только перечисленные числовые коды; текст bad или произвольное число не описывают допустимый итог.

Полный пример

#beginScript
|DOLOGIC||PARS|[1]|>|0|ENDLOGIC|
|PARS|[1] = Есть баланс
|DOLOGIC|

|DOLOGIC||PARS|[1]|<>|Есть баланс|AND||PARS|[1]|<|0|ENDLOGIC|
|CONCLUSION| = 0
|DOLOGIC|
#endScript
  1. Если первый парсер больше 0, первый условный блок заменяет его значение текстом Есть баланс.
  2. Если значение не равно Есть баланс и меньше 0, второй блок устанавливает плохой результат.
  3. При нуле ни одно действие не выполняется, потому что оба условия ложны.

Код из динамической переменной

|DV|[SharedCode] вставляет значение как обычный текст. |SB|[SharedCode] передаёт то же значение интерпретатору как код Скрипт-бокса.

Если динамическая переменная SharedCode содержит:

|PARS|[1] = Ready
|CONCLUSION| = 1

то строка:

|SB|[SharedCode]

выполняет обе команды. Переменная должна существовать, а её содержимое должно быть полноценным синтаксисом Скрипт-бокса.

Работает

Общий проверенный фрагмент хранится один раз и подключается через |SB| в нужных местах.

Ошибка

|DV|[SharedCode] не выполняет команды: он возвращает их текстовое представление.

Специальная функция SCRIPTBOX

|SCRIPTBOX| выполняет вложенный текст по правилам Скрипт-бокса из обычного выражения:

(|SCRIPTBOX||PARS|[1] = Ready|SCRIPTBOX|)

Функция изменяет состояние, возвращает пустую строку и должна быть конечной функцией выражения; предпочтительно использовать её и как начальную, как в примере выше.

Работает

Выражение используется ради присваивания |PARS|[1] = Ready, а не ради текстового результата функции.

Ошибка

Вложение |SCRIPTBOX| внутрь функции, которой нужен непустой текст, передаёт ей пустой результат.

Область видимости динамических и глобальных данных, а также влияние параллельных потоков разобраны отдельно на странице Состояние выполнения.