Как определить абсолютный путь к исполняемому файлу lua?
Пользователь
Сообщений: Регистрация: 27.05.2015
01.12.2020 20:47:57
Использовал относительный путь, но имеется несколько папок с квиками от разных брокеров и мой фреймворк почему-то "путает" папки (папки типа "С:\Quik1" , "C:\Quik2" , и т.д.). Поэтому решил использовать абсолютный путь для исключения ошибок. Как определить абсолютный путь?
Пользователь
Сообщений: Регистрация: 25.09.2020
01.12.2020 21:07:08
"С:\Quik1" , "C:\Quik2" и есть абсолютный путь. У меня тоже два Квика, но путает папки вовсе не Lua (там у меня как раз относительный путь типа F=io.open(getScriptPath().."//datafile.txt","r"), а сам Квик: при нажатии кнопки "добавить" при загрузке скриптов он открывает не папку "своего" Квика, а ту, из которой была последняя загрузка.
Пользователь
Сообщений: Регистрация: 21.08.2015
02.12.2020 01:10:21
Цитата
Владимир написал: при нажатии кнопки "добавить" при загрузке скриптов он открывает не папку "своего" Квика, а ту, из которой была последняя загрузка.
В этом конкретном случае квики путает винда. Квик просто открывает стандартный диалог, а тот сам помнит, кто что открывал последнее. Но помнит абы как, по имени программы без полного пути, вот и получается путаница. По-хорошему надо к диалогу , но квик этого не делает.
2.2.25 OnInit Функция вызывается терминалом QUIK перед вызовом функции main(). В качестве параметра принимает значение полного пути к запускаемому скрипту.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
02.12.2020 07:50:13
STRING getScriptPath() Функция возвращает путь, по которому находится запускаемый скрипт, без завершающего обратного слеша («\»). Например, C:\QuikFront\Scripts
Пользователь
Сообщений: Регистрация: 25.09.2020
02.12.2020 10:35:52
Anton, Может, и Винда - она написана не менее коряво, чем Квик. Впрочем, фиг с ними обоими - у меня сейчас идёт финальная зачистка уже моего алгоритма - все "квиковские" штучки считаю отлаженными. Последняя правка была вчера: как известно, эта скотина теряет управление при остановке скрипта, поэтому файл результатов я записываю прямо в OnStop (благо запись не обращается к утилитам основного потока), а теперь там же стал ещё и убивать окно своей таблицы. Окно-то она убивает, "зато" влетает в режим этого дурацкого ожидания, так что теперь у меня OnStop возвращает 500, чтобы не мучился свои 5 секунд, и для юзера это (аварийное) завершение смотрится как нормальное. Комедия!
Пользователь
Сообщений: Регистрация: 21.08.2015
02.12.2020 15:14:01
Цитата
Владимир написал: а теперь там же стал ещё и убивать окно своей таблицы
Код
local run = true
local tid = nil
local gcrunner = (function()
local t = {}
setmetatable(t, { __gc = function()
local t = tid
tid = nil
if t then DestroyTable(t) end
end })
return t
end)()
function main()
tid = AllocTable()
AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1)
CreateWindow(tid)
...
local run = true
local tid = nil
local file
local gcrunner = (function()
local t = {}
setmetatable(t, { __gc = function()
local t = tid
tid = nil
if t then DestroyTable(t) end
file:write("__gc\n")
file:close()
end })
return t
end)()
function OnInit(script_path)
file = io.open(script_path .. ".log", "w")
file:write("OnInit\n")
end
function main()
file:write("main\n")
tid = AllocTable()
AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1)
CreateWindow(tid)
while run do sleep(300) end
file:write("main stopped\n")
end
function OnStop()
run = nil
file:write("OnStop\n")
end
В логе:
Цитата
OnInit main OnStop main stopped
Надо делать так, как надо. А как не надо - делать не надо.
local run = true
local tid = nil
local file
local gcrunner = ( function ()
local t = {}
setmetatable(t, { __gc = function ()
local t = tid
tid = nil
if t then DestroyTable (t) end
file:write( "__gc\n" )
file:close()
end })
return t
end )()
function OnInit (script_path)
file = io.open (script_path .. ".log" , "w" )
file:write( "OnInit\n" )
end
function main ()
file:write( "main\n" )
tid = AllocTable ()
AddColumn (tid, 1 , '1' , true , QTABLE_INT_TYPE, 1 )
CreateWindow (tid)
while run do sleep ( 300 ) end
file:write( "main stopped\n" )
end
function OnStop ()
run = nil
file:write( "OnStop\n" )
end
В логе:
Цитата
OnInit main OnStop main stopped
я может плохо смотрю, но не вижу вызова функции gcrunner
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 30.01.2015
05.12.2020 00:40:28
Увидел.. от скобочек глаза заслезились ))
вообще qlua при завершении скрипта сама закрывает файлы. Видимо файл был закрыт до __gc
но это неточно )
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 21.08.2015
05.12.2020 02:51:26
Цитата
написал: но это неточно )
Точно
Код
local gcrunner = (function()
local t = {}
setmetatable(t, { __gc = function()
local t = tid
tid = nil
if t then DestroyTable(t) end
message('file type is ' .. io.type(file))
file:write("__gc\n")
file:close()
end })
return t
end)()
Пользователь
Сообщений: Регистрация: 12.05.2020
05.12.2020 12:18:31
Цитата
написал: вообще qlua при завершении скрипта сама закрывает файлы. Видимо файл был закрыт до __gc
Похоже так оно и есть.
<code> local run = true local tid = nil local file
--- Создание деструктора скрипта ----- gcrunner = {} --- Если gcrunner = {} (глобальная переменная), то __gc срабатывает только по завершению скрипта (обычно это и требуется). --- !!! А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта). setmetatable(gcrunner, { __gc = function() if tid then DestroyTable(tid) end ---- Выделенный ниже фрагмент срабатывает при запуске collectgarbage до завершения скрипта если gcrunner локальная переменная. -- При запуске функции по заверщению скрипта, выделенный фрагмент не выполняется. Функция завершается на первом операторе --- без его выполнения, но ошибка не выдается ?? file:write("__gc\n") file:close() ---- Похоже при завершении скрипта файлы открепляются раньше, чем запускается финальная уборка мусора---- end }) ---------------------------------------------------
function OnInit(script_path) file = io.open(script_path .. ".log", "w") file:write("OnInit\n") end
function main() file:write("main\n") tid = AllocTable() AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1) CreateWindow(tid) -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. while run do sleep(300) end file:write("main stopped\n") end
function OnStop() run = nil file:write("OnStop\n") end <code>
Пользователь
Сообщений: Регистрация: 12.05.2020
05.12.2020 12:33:40
Отформатированный код моего комментария:
<code> local run = true local tid = nil local file
--- Создание деструктора скрипта ----- gcrunner = {} --- Если gcrunner = {} (глобальная переменная), то __gc срабатывает только по завершению скрипта (обычно это и требуется). --- !!! А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта). setmetatable(gcrunner, { __gc = function() if tid then DestroyTable(tid) end ---- Выделенный ниже фрагмент срабатывает при запуске collectgarbage до завершения скрипта если gcrunner локальная переменная. -- При запуске функции по заверщению скрипта, выделенный фрагмент не выполняется. Функция завершается на первом операторе --- без его выполнения, но ошибка не выдается ?? file:write("__gc\n") file:close() ---- Похоже при завершении скрипта файлы открепляются раньше, чем запускается финальная уборка мусора---- end }) ---------------------------------------------------
function OnInit(script_path) file = io.open(script_path .. ".log", "w") file:write("OnInit\n") end
function main() file:write("main\n") tid = AllocTable() AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1) CreateWindow(tid) -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. while run do sleep(300) end file:write("main stopped\n") end
function OnStop() run = nil file:write("OnStop\n") end </code>
Пользователь
Сообщений: Регистрация: 21.08.2015
05.12.2020 17:05:17
Цитата
TGB написал: А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта).
Есть такое. Значит, коллектор не считает объявление переменной ссылкой на нее. Значит, надо глобально ее объявлять или хотя бы иметь где-то ссылку на нее.
Насчет функций. Если gcrunner глобальный, то выскочит сообщение, мол используете прибитый файл, а это значит, что io еще не выгружена, это ее сообщение. Получается, файл прибит не в результате выгрузки библиотеки. Я не нашел, чтобы квик явно где-то файлы закрывал или даже чтобы явно выгружал библиотеки, хотя может где и есть. Принимаем как данность. Строго говоря, финализаторы это не деструкторы, никакой порядок их выполнения не гарантируется, так что теоретически все ок, а как практически это обходить, надо думать.
Пользователь
Сообщений: Регистрация: 25.09.2020
05.12.2020 18:24:03
Вам не лень фигнёй заниматься, господа? Управление теряется, сраная интерпретируемая функция способна подвесить весь квик, а вы тут с "финализаторами-деструкторами" маетесь, да с collectgarbage воюете. НУ НЕ МОЖЕТ эта хромоногая кляча нормально работать, здесь ИДЕОЛОГИЧЕСКИХ плюх до мамы! Да, делать какие-то телодвижения в OnStop - это маразм, но там, по крайней мере, файлы прекрасно открываются, закрываются и записываются. А что ещё требуется для торгового скрипта?
Пользователь
Сообщений: Регистрация: 21.08.2015
05.12.2020 19:09:07
Цитата
Владимир написал: здесь ИДЕОЛОГИЧЕСКИХ плюх до мамы!
А выхода два: написать новый идеологически выдержанный квик (займитесь?) или лечить имеющийся, сначала поняв, рэзать ему отростки или это все же ухи.
Оно все фигня, даже если кажется, что не фигня. На конструктивную фигню арка, глядишь, и патчик сделает, а на вопли "тут все неправильно, все в топку" - нет.
Пользователь
Сообщений: Регистрация: 25.09.2020
05.12.2020 19:11:08
Anton, Нет, есть и третий вариант: использовать по максимуму имеющееся говно. Что , собссно, и сделал.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
18.12.2020 09:58:27
Цитата
TGB написал: -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc.
Вроде, не срабатывает.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 12.05.2020
18.12.2020 10:34:29
Цитата
Старатель написал: Цитата TGB написал:-- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. Вроде, не срабатывает.
Здравствуйте! При этом необходимо, чтобы gcrunner был объявлен локальным: local gcrunner = {}
написал: Цитата TGB написал:-- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. Вроде, не срабатывает.
Здравствуйте! При этом необходимо, чтобы gcrunner был объявлен локальным: local gcrunner = {}
__gc срабатывает до вызова collectgarbage, возможно при автоматической сборке.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 12.05.2020
18.12.2020 13:54:09
Цитата
Старатель написал: __gc срабатывает до вызова collectgarbage, возможно при автоматической сборке.
Мне, кажется, что ваше предположение верное. В своем комментарии с программой, внутри нее я специально отметил, что вариант с локальным объявлением gcrunner не работает в QLua 5.3.5 для финализации скрипта. Вообще то, похоже, это баг.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
18.12.2020 14:17:09
Цитата
TGB написал: вариант с локальным объявлением gcrunner
Так __gc вызывается до OnInit
Скрытый текст
Код
local run = true
local tid = nil
local gcrunner = {}
setmetatable(gcrunner, { __gc = function()
if tid then DestroyTable(tid) end
message('__gc', 2)
end })
function OnInit(script_path)
file = io.open(script_path .. ".log", "w")
file:write("OnInit\n")
message("OnInit")
end
function main()
message("main")
tid = AllocTable()
AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1)
CreateWindow(tid)
collectgarbage()
while run do sleep(300) end
end
function OnStop()
run = nil
end
Убираем какую-нибудь строку, например
Код
file:write("OnInit\n")
и срабатывает при вызове collectgarbage. Как-то так.
Цитата
TGB написал: вариант с локальным объявлением gcrunner не работает в QLua 5.3.5 для финализации скрипта.
Без collectgarbage сработает и для финализации.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 12.05.2020
18.12.2020 14:26:49
Цитата
Старатель написал: Без collectgarbage сработает и для финализации.
Дело в том, что уборка мусора может быть запущена в скрипте в процессе его работы, до его завершения и если сработает финализатор, то это ошибка.