Использовал относительный путь, но имеется несколько папок с квиками от разных брокеров и мой фреймворк почему-то "путает" папки (папки типа "С:\Quik1" , "C:\Quik2" , и т.д.). Поэтому решил использовать абсолютный путь для исключения ошибок. Как определить абсолютный путь?
"С:\Quik1" , "C:\Quik2" и есть абсолютный путь. У меня тоже два Квика, но путает папки вовсе не Lua (там у меня как раз относительный путь типа F=io.open(getScriptPath().."//datafile.txt","r"), а сам Квик: при нажатии кнопки "добавить" при загрузке скриптов он открывает не папку "своего" Квика, а ту, из которой была последняя загрузка.
Владимир написал: при нажатии кнопки "добавить" при загрузке скриптов он открывает не папку "своего" Квика, а ту, из которой была последняя загрузка.
В этом конкретном случае квики путает винда. Квик просто открывает стандартный диалог, а тот сам помнит, кто что открывал последнее. Но помнит абы как, по имени программы без полного пути, вот и получается путаница. По-хорошему надо к диалогу прицеплять уникальный идентификатор, но квик этого не делает.
2.2.25 OnInit Функция вызывается терминалом QUIK перед вызовом функции main(). В качестве параметра принимает значение полного пути к запускаемому скрипту.
STRING getScriptPath() Функция возвращает путь, по которому находится запускаемый скрипт, без завершающего обратного слеша («\»). Например, C:\QuikFront\Scripts
Anton, Может, и Винда - она написана не менее коряво, чем Квик. Впрочем, фиг с ними обоими - у меня сейчас идёт финальная зачистка уже моего алгоритма - все "квиковские" штучки считаю отлаженными. Последняя правка была вчера: как известно, эта скотина теряет управление при остановке скрипта, поэтому файл результатов я записываю прямо в OnStop (благо запись не обращается к утилитам основного потока), а теперь там же стал ещё и убивать окно своей таблицы. Окно-то она убивает, "зато" влетает в режим этого дурацкого ожидания, так что теперь у меня OnStop возвращает 500, чтобы не мучился свои 5 секунд, и для юзера это (аварийное) завершение смотрится как нормальное. Комедия!
Владимир написал: а теперь там же стал ещё и убивать окно своей таблицы
Код
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
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)()
s_mike@rambler.ru написал: вообще 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>
<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>
TGB написал: А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта).
Есть такое. Значит, коллектор не считает объявление переменной ссылкой на нее. Значит, надо глобально ее объявлять или хотя бы иметь где-то ссылку на нее.
Насчет функций. Если gcrunner глобальный, то выскочит сообщение, мол используете прибитый файл, а это значит, что io еще не выгружена, это ее сообщение. Получается, файл прибит не в результате выгрузки библиотеки. Я не нашел, чтобы квик явно где-то файлы закрывал или даже чтобы явно выгружал библиотеки, хотя может где и есть. Принимаем как данность. Строго говоря, финализаторы это не деструкторы, никакой порядок их выполнения не гарантируется, так что теоретически все ок, а как практически это обходить, надо думать.
Вам не лень фигнёй заниматься, господа? Управление теряется, сраная интерпретируемая функция способна подвесить весь квик, а вы тут с "финализаторами-деструкторами" маетесь, да с collectgarbage воюете. НУ НЕ МОЖЕТ эта хромоногая кляча нормально работать, здесь ИДЕОЛОГИЧЕСКИХ плюх до мамы! Да, делать какие-то телодвижения в OnStop - это маразм, но там, по крайней мере, файлы прекрасно открываются, закрываются и записываются. А что ещё требуется для торгового скрипта?
Оно все фигня, даже если кажется, что не фигня. На конструктивную фигню арка, глядишь, и патчик сделает, а на вопли "тут все неправильно, все в топку" - нет.
TGB написал: -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc.
Вроде, не срабатывает.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Цитата TGB написал:-- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. Вроде, не срабатывает.
Здравствуйте! При этом необходимо, чтобы gcrunner был объявлен локальным: local gcrunner = {}
Старатель написал: Цитата TGB написал:-- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. Вроде, не срабатывает.
Здравствуйте! При этом необходимо, чтобы gcrunner был объявлен локальным: local gcrunner = {}
__gc срабатывает до вызова collectgarbage, возможно при автоматической сборке.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: __gc срабатывает до вызова collectgarbage, возможно при автоматической сборке.
Мне, кажется, что ваше предположение верное. В своем комментарии с программой, внутри нее я специально отметил, что вариант с локальным объявлением gcrunner не работает в QLua 5.3.5 для финализации скрипта. Вообще то, похоже, это баг.
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 сработает и для финализации.
Надо делать так, как надо. А как не надо - делать не надо.