Аргументы action/condition

Здесь обсуждается всё, что касается макросов.
Post Reply
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

Сигнатуры функций отличаются:

Code: Select all

condition(akey,data)

Code: Select all

action(data)
(Дополнительный параметр akey появился в связи с тем, что макрофункция mf.akey в condition не работает.)

Предлагаю обсудить вот что:
Можно ли (и нужно ли) привести состав аргументов к единому виду, учитывая что потенциально может быть полезным передавать и другие аргументы.
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

John Doe wrote: Mon 09 Dec, 2019 09:15 передавать и другие аргументы.
Я считаю полезным передавать также состояние макроса: viewtopic.php?p=157563#p157563
Через это состояние можно было бы передавать значения из condition в action: viewtopic.php?p=157561#p157561
Туда же на мой взгляд вписывается и пожелание о передаче разобранного регэкспа: https://bugs.farmanager.com/view.php?id=2310
Также (в перспективе) через этот объеккт можно было бы обращаться какие-то дополнительные методы, относящиеся именно к состоянию текущего вызова макроса.
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

John Doe wrote: Mon 09 Dec, 2019 09:15 привести состав аргументов к единому виду
Это конечно необязательно, но имхо было бы удобнее.

Добавить в action первым параметром akey очень просто, но не очень полезно.
Но что если заменить akey на таблицу-состояние?
Совместимость можно попытаться сохранить с помощью метаметодов.
Shmuel
Posts: 6836
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Аргументы action/condition

Post by Shmuel »

John Doe wrote: Mon 09 Dec, 2019 09:15 Можно ли (и нужно ли) привести состав аргументов к единому виду, учитывая что потенциально может быть полезным передавать и другие аргументы.
Состав аргументов уже был разный в последние годы, и это вроде не мешало.
John Doe wrote: Mon 09 Dec, 2019 09:23 Я считаю полезным передавать также состояние макроса
Данная таблица-аргумент - она и есть состояние макроса (во всяком случае так было задумано).
John Doe wrote: Mon 09 Dec, 2019 09:23 Туда же на мой взгляд вписывается и пожелание о передаче разобранного регэкспа

Code: Select all

condition=function(akey,data) data.reg1=regex.new("abc"); return true; end;
action=function(data) if data.reg1:match("zz abc") then ... end; end;
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

Shmuel wrote: Mon 09 Dec, 2019 15:27 Состав аргументов уже был разный в последние годы, и это вроде не мешало.
"Состав аргументов" громко сказано, одна функция получала (единственный) аргумент, другая нет.
Shmuel wrote: Mon 09 Dec, 2019 15:27 Данная таблица-аргумент - она и есть состояние макроса (во всяком случае так было задумано).
Задумано как таблица, разделяемая между любыми запусками.
Хочется же ограничить состояние конкретным запуском, в противном случае возможны ситуации, когда эта таблица, являясь upvalue какой-то функции, уже будет отражать состояние другого запущеного макроса.
Shmuel wrote: Mon 09 Dec, 2019 15:27 condition=function(akey,data) data.reg1=regex.new("abc"); return true; end;
action=function(data) if data.reg1:match("zz abc") then ... end; end;
Пожелание заключалось в том, чтобы получать уже разобранный регэксп, поскольку:
1) луамакро его уже разобрал, и незачем это делать повторно
2) но главное в другом: разбирая сочетание вручную можно получить немного другие результаты, именно этого прежде всего хочется избежать.
Shmuel
Posts: 6836
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Аргументы action/condition

Post by Shmuel »

John Doe wrote: Mon 09 Dec, 2019 16:44 Задумано как таблица, разделяемая между любыми запусками.
Хочется же ограничить состояние конкретным запуском
Приведите практический пример полезного применения этого гипотетического состояния.
John Doe wrote: Mon 09 Dec, 2019 16:44 Пожелание заключалось в том, чтобы получать уже разобранный регэксп
Сейчас, возможно, это будет проще сделать, поместив результат разбора в таблицу-аргумент.

P.S. Если есть опасения, что вызов нового макроса затрёт информацию о разобранном регекспе, то можно самым первым действием функции action поместить эту информацию в локальную переменную. Просто добавлять ещё один аргумент в condition и action ради данного специфического случая кажется мне не очень оправданным.
Last edited by Shmuel on Mon 09 Dec, 2019 23:04, edited 1 time in total.
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

Shmuel wrote: Mon 09 Dec, 2019 22:21 Приведите практический пример полезного применения этого гипотетического состояния.
Передача данных из condition в action.
Это частая задача, решается использованием общего upvalue.
(Теперь можно использовать таблицу макроса, но это ничего принципиально не меняет, т.к. не спасает от ошибки)
И в какой-то момент я поймал не гипотетический а вполне реальный баг, источником которого являлось именно то, что значение upvalue (неожиданно для меня) изменялось, другим запуском этого же макроса.
Я сейчас не вспомню конкретный макрос, но код мог бы быть например таким:

Code: Select all

local upvalue;
Macro {
 --
 action=function()
   far.Timer(function()
     -- use upvalue
   end)
 end;
}
Shmuel wrote: Mon 09 Dec, 2019 22:21 Если есть опасения, что вызов нового макроса затрёт информацию о разобранном регекспе, то можно самым первым действием функции action поместить эту информацию в локальную переменную
Совершенно верно, но абсолютно неочевидно, пока не напорешься на свой баг, и собственноручно не найдёшь суть проблемы.
Shmuel wrote: Mon 09 Dec, 2019 22:21 Сейчас, возможно, это будет проще сделать, поместив результат разбора в таблицу-аргумент.
Да, таблица удобна тем, что легко при необходимости добавлять новые поля, не теряя при этом совместимости.
Но при этом я всё же хочу чётко отделить общие и постоянные свойства макроса от состояний, актуальных в конкретном запуске (и таковых может найтись значимое количество, не сейчас так в будущем).
Shmuel wrote: Mon 09 Dec, 2019 22:21 Просто добавлять ещё один аргумент в condition и action ради данного специфического случая кажется мне не очень оправданным.
Момент с моей точки зрения не столько специфический, сколько концептуальный, и позволяюший лучше защититься от багов, сложных в отладке.
Но я согласен, что аргументов на всё не напасёшься, почему и предложил сделать это первым аргументом, вместо AKEY, убивая при этом двух зайцев разом:
- аргумент AKEY уже есть (в condition), надо только сделать его таблицей (и предусмотреть метаметоды для совместимости)
- функции action и condition будут иметь одинаковую сигнатуру, что удобно и для запоминания, и для документирования.
User avatar
buniak_a_h
Posts: 4266
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 644 times
Contact:

Аргументы action/condition

Post by buniak_a_h »

John Doe, к Вашему примеру с upvalue: я частенько использую семафор (типа пока некая upSem ~= nil condition = false. В action перенос upSem в переменную внутри функции и присвоение upSem = nil. Например, так в "диалоговом" режиме известного Вам ClickTiTitleDir. Если забудешь - проблема...
User avatar
HaRT
Moderator
Posts: 10865
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Аргументы action/condition

Post by HaRT »

Shmuel wrote: Mon 09 Dec, 2019 22:21 Приведите практический пример полезного применения этого гипотетического состояния.
Я в целом согласен с доводами John Doe (и в концептуальном плане, и в плане предотвращения сложноотлавливаемых ошибок).
От себя же добавлю, что выделение конкретного запуска макроса в отдельную сущность, не тождественную самому макросу, будет полезно ещё и для макросов, запускаемых через eval (либо через Mode=2, либо из файла, в т.ч. того же, где вызывающий макрос).
%FarHome%\Encyclopedia\luafar_manual.chm wrote:Если "Key" обнаружен, то состояние текущего макроса сохраняется и начинает выполняться макрос, назначенный на сочетание клавиш S. После исполнения S прерванный макрос продолжает работать.
Вот как раз в этом «состоянии» и стоило бы хранить ту таблицу, про которую я говорю.
Last edited by HaRT on Tue 10 Dec, 2019 13:46, edited 1 time in total.
Reason: Добавлен абзац с цитатой из документации по макросам
Фар есть инструмент, а не нянька. © 2009 DrKnS
Shmuel
Posts: 6836
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Аргументы action/condition

Post by Shmuel »

Внутреннее состояние исполняемого макроса - это состояние внутренних переменных (upvalues) функции action.
То, что называется в данной ветке внутренним состоянием - это возможность передать данные в action из плагина либо из condition.
Из condition это легко делается прямо сейчас (ну да, надо скопировать в локальную переменную).
Из плагина ("разобранный регексп") - надеюсь как-нибудь дойдут руки (тикет сильно старый, мне даже неудобно),
User avatar
HaRT
Moderator
Posts: 10865
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Аргументы action/condition

Post by HaRT »

Shmuel wrote: Tue 10 Dec, 2019 18:29 Из condition это легко делается прямо сейчас (ну да, надо скопировать в локальную переменную).
Как предлагается делать, когда надо что-то передавать из condition в action в случае рекурсивного вызова макроса? Важно, (1) чтобы разные уровни вложенности друг другу не мешали и (2) чтобы это было удобно (в т.ч. не провоцировало лишние ошибки в логике обработки данных).
Фар есть инструмент, а не нянька. © 2009 DrKnS
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

(1) Процитированное работает, и при рекурсивном вызове. Но об этой технике надо знать (понимать и помнить).
(2) И в этом плане таблица-аргумент удобнее сама по себе, и потому будет способствовать правильному использованию даже если нигде в документации не будет акцентировано почему так.
Shmuel
Posts: 6836
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Аргументы action/condition

Post by Shmuel »

John Doe wrote: Tue 10 Dec, 2019 18:45 (2) И в этом плане таблица-аргумент удобнее сама по себе, и потому будет способствовать правильному использованию даже если нигде в документации не будет акцентировано почему так.
По поводу этого нет спора, вопрос лишь в том, оправдывает ли этот редко встречающийся и нетипичный класс задач добавления ещё одного параметра. Например, в отношении condition - передача из неё данных является совершенно нецелевым использованием, функция предназначена совсем для другого.
User avatar
John Doe
Бюрократ
Posts: 13855
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 428 times
Contact:

Аргументы action/condition

Post by John Doe »

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

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

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

Return to “Обсуждение макросов”