Upvalues
Локальные переменные, доступные из функций одного или нескольких макросов (upvalues), являются общими для этих функций и сохраняют свои значения между вызовами макросов. Их значения сбрасываются в исходные при выполнении любой операции загрузки макросов.
Пример:
local var = 15
function inc_var() var = var+1 end
function dec_var() var = var-1 end
buniak_a_h wrote: Эти переменные присваиваются в функциях condition.
Возможно, но в самом определении макроса этого не видно, а присваивания эти не находятся в одном месте, а встречаются неоднократно и в разных функциях.
И используются присвоенные значения тоже повсеместно, а не только в функциях action.
buniak_a_h wrote: Не нашёл, где такое может быть описано.
А это тут при чём вообще.
Я описываю ситуацию, когда событие ProcessEditorEvent может придти для фонового редактора.
buniak_a_h wrote: Но не представляю себе, как можно открыть новый редактор, а старый "спрятать" (чтоб на него нельзя было переключиться).
Открыть модальный редактор.
buniak_a_h wrote: Если этого не сделать, то исходный текст возможно будет править,
John Doe wrote: buniak_a_h писал(а):
Источник цитаты Т.к. я не знаю, какое время жизни переменных
macroapi_manual.ru.chm
А если несколько экземпляров FAR - переменные общие, или нет? А editor.info.id - уникальный? Или всё в пределах одного экземпляра? Что как-то они между собой взаимодействуют - я понял. Во всяком случае, пока ВСЕ экземпляры не закроются, значение, занесённое в _G, остаётся доступным. Впрочем, начерно, _G.EditorsCondView можно заменить на local EditorsCondView - попробую.
John Doe wrote: А это тут при чём вообще.
Тут это - ни при чём. Просто нужно же иметь механизм прерывания цепочки обработчиков события (типа done). Просто чтоб другой обработчик не вмешался в работу макроса.
John Doe wrote: Я описываю ситуацию, когда событие ProcessEditorEvent может придти для фонового редактора.
1. Не знаю, что такое "фоновый редактор".
2. Если фоновый редактор в состоянии condenced, то обрабатывать надо независимо от того, фоновый он или нет. В начале функции ProcessEditorEvent я же проверяю if not _G.EditorsCondView[id] then return end - т.е. включен ли сжатый режим. И что тут не так?
John Doe wrote: Открыть модальный редактор
И потерять возможность переключаться в другие окна??? Ну ничего себе! Нужно запретиь переход только на исходный редактор, а не вообще на любой!
John Doe wrote: Или просто запретить модификацию.
Опять же не представляю, как запретить модификацию без перехвата нажатий клавиш. Собственно, я запретил модификацию в сжатом режиме.
John Doe
Может, поможете с таким вопросом:
Я в документации (macroapi_manual.ru.chm, раздел "Обработчики событий") нашёл такую фразу:
Функции condition и action обработчика вызываются с теми же параметрами, с которыми вызывается соответствующая экспортируемая функция (см. мануал LuaFAR).
Что такое "соответствующая экспортируемая функция"? Поиск по condition ничего не дал, в разделе export.ProcessEditorEvent параметры абсолютно не соответствующие тем, что получают функции (первый параметр я получаю таблицу, а описан EditorID: integer.
Я использовал то, что подсмотрел в других макросах (в частности, LuaSpell.lua, EditWrap.lua). И почему-то работает. Чего-то я не понимаю...
О! Как-то мимо моего внимания Ваш пост проскочил...
John Doe wrote: Я тут критикую избыточную область действия переменных ei, EID, объявленных в самом начале скрипта.
Утверждаю, что общие переменные необходимы только в макросах, для передачи значений из condition в action (поскольку других механизмов для этого не предусмотрено).
Так у меня именно так и делается (и именно для этого и используются)! В функции IsEditorActive эти переменные присваиваются, а используются в функциях action. Т.е. в точности то, что Вы написали...
buniak_a_h wrote:в разделе export.ProcessEditorEvent параметры абсолютно не соответствующие тем, что получают функции (первый параметр я получаю таблицу, а описан EditorID: integer.
Довольно серьёзное заявление. Можете доказать на примере, чтобы не было голословно?
buniak_a_h wrote: А если несколько экземпляров FAR - переменные общие, или нет?
Разные экземпляры никак между собой не взаимодействуют.
buniak_a_h wrote: Тут это - ни при чём.
Значит и нечего мешать всё в кучу. Если что-то в Энциклипедии не ясно, значит надо спросить, но в соответствующей теме.
buniak_a_h wrote: В начале функции ProcessEditorEvent я же проверяю if not _G.EditorsCondView[id] then return end - т.е. включен ли сжатый режим. И что тут не так?
А то, что id может оказаться не равным EID, если редактор фоновый (т.е. не является активным окном).
buniak_a_h wrote: Нужно запретить переход только на исходный редактор, а не вообще на любой!
И так можно, всё в ваших руках.
buniak_a_h wrote: Собственно, я запретил модификацию в сжатом режиме.
Оказывается умеете.
buniak_a_h wrote: не представляю, как запретить модификацию без перехвата нажатий клавиш.
И перехватить можно, да.
buniak_a_h wrote: Может, поможете с таким вопросом:
local a
Macro {
area="Editor";
condition=function()
a = 1
end;
action=function()
far.Show(a)
end;
}
Здесь область действия переменной ограничена двумя функциями, и это видно невооружённым глазом, соответственно откуда пришло значение очевидно, и также можно не беспокоиться о том, что переменная будет модифицирована где-то в другом месте.
А у вас:
1. Переменные общие для нескольких макросов (нормально, но уже надо быть внимательнее)
2. Визуально проконтроллировать сложно, поскольку используются переменные не в теле action/condition, а в ранее определённых функциях, которые откуда только не вызываются (не только из макросов).
3. Таких функций много, одна вызывается из другой и т.п. (ну можно же передавать значения параметрами, почему не пользуетесь)
4. Эти же переменные используется в обработчиках событий, и в этом случае мне уже совсем неясно, где предполагается их инициализация.
Я даже готов поверить, что вы свой код видите насквозь, и всё там предусмотрено.
Я только утверждаю, что практика эта плохая. Такой код сложно понимать, и модифицировать.
John Doe
Т.е. если я вместо вызова функций в каждом condition буду делать одно и то же (получение Editor.ID-а), то это будет хорошая практика, а объединение одинакового кода в функцию - для LUA считается плохой? Ну, перенести кусок текста - дело секундное. Видимо, я неправильно понимаю стиль и критерии эффективности LUA и FAR
Хотя что-то внутри протестует. 40-летний опыт программирования, видимо...
local a
Macro {
area="Editor";
condition=function()
a = f1() -- одинаковый код объединённый в функцию
end;
action=function()
f2(a) -- другая процедура которой нужен доступ к нашей переменной
end;
}
Я не утверждаю что надо вот прям только так, но надо стремиться к ясности
Заранее прошу прощения за нубский вопрос: а что мешает нам поместить переменную a прямо в „таблицу“ (?) Macro?
Где бы почитать, что эти Macro собой представляют с точки зрения виртуальной машины Lua?
1. Насколько я понимаю, код в принципе нерабочий. condition должна возвращать или boolean, или число-приоритет. а a в Вашем примере - это (в моём контексте) пара (ei, EID).
2. Да я, вроде, практически так и написал. Замените f1 на IsEditorActive, f2 на CondViewOff (или CondViewOn) - получится тот же код
John Doe wrote: а, в коде condition недостаёт return, добавьте самостоятельно.
Это я как раз понял. Не в этом ошибочка. return a не годится (a - пара ei, EID, а нужна или boolean, или number); видимо, под [b]a[/b] имеется в виду внешняя (по отношению к функциям) local a; а тогда зачем передавать её в f2 параметром?