Инструменты пользователя

Инструменты сайта


ru:documentation:beta

Бета-функционал

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

Критические изменения

В целом, совместимость со старыми скриптами сохраняется, но некоторые изменения в новой версии могут вызвать неработоспособность скрипта:

  1. Строки без кавычек в условиях и выражениях теперь не разрешены по умолчанию.
  2. Убрана команда AutorunBlockUnload.
  3. Убран старый синтаксис FileExists в условиях.
  4. Убрана директива AutorunAllowWriteEnv.
  5. Убрана директива AutorunLoadInSubrocess за отсутствием реальной необходимости.

Просьба внимательно прочитать раздел по переходу на новую версию.

Как перейти на новую версию

1. Строки без кавычек в условиях и выражениях теперь не разрешены по умолчанию.

Рекомендуется прочитать раздел Синтаксис для понимания различий двух видов синтаксиса в Autorun и причин их существования.

Можно просто включить директиву LegacyExpressions, но рекомендуется внести изменения для поддержки актуального режима работы.

Необходимо, чтобы все строки в выражениях (в том числе вычисляемых строках) были в кавычках - двойных или одинарных.

Некоторые примеры:

Было:
if %MYVAR% = text then
Стало:
if MYVAR = "text" then  
или 
if %MYVAR% = "text" then

Было:
if not FileExist(%COMMANDER_PATH%\NoClose.exe) then
Стало:
if not FileExist("%COMMANDER_PATH%\NoClose.exe") then
или
if not FileExist(%COMMANDER_PATH% & "\NoClose.exe") then

Было:
if IniRead(%COMMANDER_INI%, Configuration, LanguageIni) then
Стало:
if IniRead(%COMMANDER_INI%, "Configuration", "LanguageIni") then
или
if IniRead(%COMMANDER_INI%, 'Configuration', 'LanguageIni') then

Было:
%"IniRead(%COMMANDER_INI%, Configuration, LanguageIni)"
Стало:
%"IniRead(%COMMANDER_INI%, 'Configuration', 'LanguageIni')"
или
%'IniRead(%COMMANDER_INI%, "Configuration", "LanguageIni")'

2. Убрана команда AutorunBlockUnload

Необходимо внести следующие изменения:

Было:
AutorunBlockUnload(Yes)

Стало:
Pragma AutorunBlockUnload

3. Убран командный синтаксис FileExist/ProcessExist в условиях.

Необходимо внести следующие изменения:

Было:
If FileExist "file" Then

Стало:
If FileExist("file") Then

4. Убрана директива AutorunAllowWriteEnv

К сожалению, нет другого варианта, кроме как переписать код или использовать старую версию. Работа этой директивы неприменима в новой версии.

Синтаксис

Командный синтаксис

В ранних версиях Autorun, до момента, когда появились условия, использовался только один вид синтаксиса — командный. Этот вид синтаксиса широко используется для передачи приложению параметров в командной строке и обычно включает в себя список параметров, следующих один за другим, и переключателей, которые могут располагаться в произвольном порядке (в Autorun переключатели должны располагаться до параметров). В примере ниже будет запущена 64-битная версия Total Commander в свернутом состоянии:

ShellExec /SW_MINIMIZE "%COMMANDER_PATH%\Totalcmd64.exe"

Этот вид синтаксиса использует разделение параметров пробелами, если в тексте параметра содержится пробел — то параметр берется в кавычки. Также текст параметров может содержать переменные Autorun или переменные окружения, в примере выше %COMMANDER_PATH% — это переменная окружения, содержащая путь к Total Commander.

К плюсам такого синтаксиса можно отнести простоту записи и обработки параметров, возможность в относительно компактной записи реализовывать сложную логику.

Но есть и минусы. Если команда должна возвращать значение, такая запись становится неудобной. Также практически невозможно использовать команды напрямую в выражениях (в частности в условиях).

Важная особенность записи команд в этом синтаксисе: вычисляемые строки в параметрах выполняются после входа в команду. В функциональном синтаксисе выражения в параметрах выполняются перед входом в функцию.

Функциональный синтаксис

Функциональный синтаксис призван решить недостатки командного. Такой способ записи (с вариациями) широко используется в большинстве языков программирования. Пример:

p = StrPos("abcdefgh", "cd")

В результате в переменную «p» будет записан результат выполнения функции 3 — позиция подстроки.

Функциональный синтаксис удобен для использования в выражениях: в операциях присваивания, условиях, определениях функций. Например:

if StrPos("abcdefgh", "cd") = 3 then MsgBox("Yes")

В этом коде, если позиция подстроки равна 3, то вызывается команда MsgBox, выдающая сообщение.

В отличие от командного синтаксиса использовать переменные прямо в тексте здесь нельзя. Переменная находится в выражении отдельно, что нужно делать с ее значением определяется стоящими рядом операторами:

a = 1
b = a + 1 --> b = 2, сложение
b = a & 1 --> b = 11, конкатенация (соединение двух строк)

Интерпретация функционального синтаксиса

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

Интерпретация определяется директивой LegacyExpressions. При ее наличии будет использоваться старая интерпретация.

Различия между актуальной и старой реализацией следующие:

Актуальная:

  1. Все строки должны быть кавычках (любых из двух типов)
  2. Переменные в выражениях используются без символов %, но могут быть и заключены в них.
  3. При использовании в выражении отсутствующей переменной выдается ошибка.
  4. Нет неоднозначностей в выражениях.

Предыдущая:

  1. Строки могут быть в кавычках (любых из двух типов), либо без кавычек, но только если строка не содержит пробелов и разделителей.
  2. Переменные должны быть заключены в %%.
  3. В случае отсутствия переменной возвращается само имя переменной, ошибок не выдаётся.
  4. Возможны неоднозначности в выражениях, что может привести к сложнодиагностируемым ошибкам.

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

Некоторые примеры работы двух интерпретаций:

Актуальный
a = "zxc"                -- ок
c = %a%                  -- ок, присвоит значение a
c = a                    -- ок, присвоит значение a
b = StrLen("qwerty")     -- ок
b = StrLen(%a%)          -- ок
b = StrLen(a)            -- ок
b = StrLen(a & "qwerty") -- ок

Старый
a = "zxc asd"               -- ок
a = zxc                     -- ок
c = %a%                     -- ок, присвоит значение a
c = a                       -- ок, присвоит строку "a"
b = StrLen(qwerty)          -- ок
b = StrLen("qwerty")        -- ок
b = StrLen(%a%)             -- ок
b = StrLen(a)               -- ок, вернет "1", длину строки "a"
b = StrLen("qwerty asdf")   -- кавычки обязательны, т.к. пробел
b = StrLen("qw(er)ty,asdf") -- кавычки обязательны, т.к. в строке есть разделители ",()"
b = StrLen(%a% & qwerty)    -- ок

Пример неоднозначности:
While %h% > 0
  h = %h% - 1
Wend
-->  при отсутствии объявленной переменной произойдет немедленный выход из цикла, 
т.к. будет возвращено "%h%" - строка, которая не приводится к числу, следовательно = 0

Основы

Длинные строки могут быть разделены на несколько строк. Для этого используется комбинация пробела с символом подчеркивания « _»:

MsgBox("Text", _
"Title")

При слиянии строк комбинация « _» (в том числе пробел) убирается.

Директивы

Pragma Include <filename>

Загружает дополнительный файл со скриптом в формате Autorun. Это может быть библиотека нужных пользовательских функций, или основной скрипт Autorun, вынесенный в другое место. Путь может быть относительным каталога Autorun, в нем также могут использоваться переменные окружения (но не внутренние переменные!).

Обратите внимание, что загрузка происходит на этапе препроцессинга, а значит, условия здесь еще не работают.

Pragma IncludeOnce

Директива может находиться в начале подключаемого файла (в основном скрипте смысла не имеет). Сообщает препроцессору, что содержимое файла должно быть вставлено только один раз, что помогает избежать дублирования определения функций. Если директива отсутствует, содержимое файла будет вставлено столько раз, сколько будет встречена директива Include с именем этого файла.


Циклы

В Autorun реализовано два типа циклов.

For .. Next

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

For var = <expr> To <expr> [Step <expr>]
...
Next

Пример

For var = 1 To 4
  MsgBox(var) --> 1 --> 2 --> 3 --> 4
Next

While.. Wend

Цикл по условию. Выполняется, пока условие истинно.

While <expr>
...
Wend

Пример

var = 3
While var > 0
  MsgBox(var) --> 3 --> 2 --> 1
  var = var - 1
Next

В циклах могут быть использованы ключевые слова Break и Continue для управления потоком выполнения.

var = 3
While True
  var = var + 1
  If var < 10 Then Continue
  Break
Next

var --> 10

:!: Внимание! Не создавайте пустых циклов и долго выполняющихся циклов без использования задержки. Это может привести к повышенной нагрузке на процессор.


Переменные

Переменные в Autorun могут быть глобальные и локальные. Локальные переменные имеют смысл только внутри функций.

Global [Const] Var1 [= expr] [, Var2 [= expr] .. [, VarN [= expr]]
Local [Const] Var1 [= expr] [, Var2 [= expr] .. [, VarN [= expr]]
Const Var1 [= expr] [, Var2 [= expr] .. [, VarN [= expr]]

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

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

Const - переменная будет константой. В основном имеет смысл использовать совместно с Global и/или в основном теле скрипта, поскольку значение локальной переменной исчезает при выходе из функции. После первичного создания переменной значение константы изменить нельзя.

Также возможно задавать переменные без предварительного определения:

Var1 = expr
Var2 = expr

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

var1 = 1
var2 = 1

MyFunc()

Func MyFunc()
    Local var1 = 123
    var2 = 123
    Global var3 = 123    
    var4 = 123
    Local var5 = 123
EndFunc

var1 --> 1
var2 --> 123
var3 --> 123
var4 --> undefined
var5 --> undefined

Функции

Пользовательские функции задаются с помощью ключевых слов Func с последующим именем функции и списком параметров в скобках, и EndFunc. Параметры разделяются запятой.

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

В функциях могут быть заданы 4 вида формальных параметров:

  • Простой параметр
  • Параметр «по ссылке»
  • Параметр со значением по умолчанию
  • Открытый список параметров

Простой параметр

Простой параметр задается просто именем переменной. Значение актуального параметра будет вычисляться перед передачей в функцию.

MyFunc(123+456)

Func MyFunc(var)
    MsgBox(var) --> 579
EndFunc

Параметр "по ссылке"

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

a = 1

MsgBox(a) --> 1

MyFunc(a)

Func MyFunc(ByRef var)
    MsgBox(var) --> 1
    var = 123
EndFunc

MsgBox(a) --> 123

Параметр со значением по умолчанию

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

MyFunc("text")
MyFunc("text", "My title")

Func MyFunc(var1, var2 = "Default title")
    MsgBox(var1) --> text
    MsgBox(var2) --> Default title --> My title
EndFunc

Открытый список параметров

Параметр задается специальным значением «…» и позволяет задавать неограниченный список входных параметров. Этот параметр должен находиться в самом конце списка формальных параметров, всё что после него будет проигнорировано. Получение параметра производится с помощью функции Args:

MyFunc(123, 456, 789)

Func MyFunc(...)
    For i = 1 To Args()
        MsgBox(Args(i), i) --> 123 --> 456 --> 789
    Next
EndFunc

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

r = MyFunc(1)

r --> Positive

Func MyFunc(var)
  If var > 0 Then
    Return "Positive"
  ElseIf var < 0 Then
    Return "Negative"
  Else
    Return "Zero"      
  EndIf
EndFunc

Args

Функция предназначена для получения параметров функции, переданных открытым списком.

Args([индекс])

Параметры

индексИндекс получаемого параметра. Начинается с 1. Если опущен, возвращается число переданных параметров.

Call

Call FuncName [ Param1 [ Param2 .. [ ParamN]]]
Call("FuncName" [, Param1 [, Param2, .. [, ParamN]]])

Параметры

FuncNameИмя вызываемой функции.
ParamИмя вызываемой функции.

Возвращаемое значение

Значение, возвращаемое функцией, имя которой задано первым параметром (только в функциональной записи).

Пример

a = "MsgBox"
Call(a, "Text", "Title")

Примечания

Используйте эту функцию только при необходимости вызова функции или команды, имя которой нужно передавать в переменной (т.е. на этапе написания скрипта не определено, какую именно функцию нужно будет запускать). В остальных случаях предпочтительнее прямой вызов функции.


Eval

Вычисляет выражение, заданное строкой.

Eval "expression"
Eval("expression")

Параметры

«expression»Строка с вычисляемым выражением.

Возвращаемое значение

Значение, полученное в результате вычисления заданного строкой выражения (только в функциональной записи).

Пример

a = 4
Eval("1+2+3+a") -- > 10

Примечания

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

ru/documentation/beta.txt · Последние изменения: 2020/06/07 23:13 — loopback

Инструменты страницы