Да, это скомпилировалось.
Сам Кронос не упал насмерть
Но сказал вот такое:
Модуль: Form: (2) [Conversion01]
Строка 107: attempt to index local 'res' (a nil value)
Стек вызовов:
Form: (2) [Conversion01] :107: in function <at string:106>
Form: (2) [Conversion01] :108: in function <at string:93>
Form: (2) [Conversion01] :157: in function 'ReReadSimpleConvForTransfer2'
Form: (2) [Conversion01] :833: in function <at string:831>
local base=CroApp.GetBank():GetVocabulary():GetBase("XX")
if base then for r in (function(R) if R then
R:Sort{{field=5,descent=true},{field=7},{field=10}}
return R.Records
end return pairs({})
end)(base.RecordSet)
do arrSimpleConv[#arrSimpleConv+1]={Type=r:GetValue(5),
LegName=r:GetValue(10),
PickName=r:GetValue(11),
Rules = (function() local res={}
for i,p in ipairs(r:GetValue(20, 0))
do res[i]=table.unserialize(p)end
return res
end)(),
FlagHierarch=tonumber(r:GetValue(30)),
}
end end
Что-то перестал даже ваш первый вариант работать, который точно работал.
Потыкал ещё немного - очень похоже, что нельзя делать for x in ??? по переменной ???, которая хранит Records. Там обязательно должен быть callale object, как я понял. Т.е. или rst.Records, или через ваше замыкание всё равно сначала вернуть RecordSet, а for всё-таки уже явно брать от вызова Records. Кажется только так работает.
Сдалась же вам эта история. Ставропольский край с Тюменской областью лет семь назад это приняли и применили. Конкретно это место - ровно по одному разу каждый.
В общем, если ужас как хочется зачем-то обмазываться анонимными функциями, то вот так работает:
local rst = (function(base)
if base then
local R = base.RecordSet; R:Sort{{field=5,descent=true},{field=7},{field=10}}
return R
end end)(CroApp.GetBank():GetVocabulary():GetBase("XX"))
for r in rst.Records do
а без rst тоже самое - крашится
for r in ((function(base)
if base then
local R = base.RecordSet; R:Sort{{field=5,descent=true},{field=7},{field=10}}
return R
end end)(CroApp.GetBank():GetVocabulary():GetBase("XX"))).Records do
Могу пофантазировать на предмет стека и процедуры встраивания Lua там. Но боюсь сильно наврать.
for r in (function(base)
local R={}
if base then
R = base.RecordSet; R:Sort{{field=5,descent=true},{field=7},{field=10}}
R=R.Records
end return R end) -- pairs(R)??
(CroApp.GetBank():GetVocabulary():GetBase("XX")) do
Очень простой механизм. Поля метатаблицы определяют поведение (чтение/запись, перегрузка операторов и т.д.) таблиц, на которых эта метатаблица висит. Скорее всего, ты не осилил __index и __newindex, но там тоже просто. Если на таблице A висит метатаблица B, и в A нет поля x, то чтение этого поля будет осуществляться через B.__index; аналогично с записью через __newindex.
Но вообще, для классов можно было взять чужую реализацию. Например, из библиотеки hump.
Это вообще не проблема, не могу вспомнить ни одну ошибку, связанную с глобальными переменными года за 3. Возможно, дело в использовании luacheck, но вот как-то так.
Оператор GOTO нарушает обратную совместимость между версиями.
Ты о чём?
Да и встраивание в СИ не сказать чтобы простое…ну это еще ладно. Нерукожоп справится.
Я рукожоп, но как-то справился. Нужно всего-то понять, как работать с Луашным стеком. Можно даже в исходники стандартной библиотеки заглянуть за примерами, там ничего страшного.
for r in (function(base) local E=pair({})
if not base then return E end local R=base.RecordSet
if not R then return E end
R:Sort{{field=5,descent=true},{field=7},{field=10}}
return R.Records -- is Records iterable?!
end)
(CroApp.GetBank():GetVocabulary():GetBase("XX")) do
Сначала выяснилось, что крашится если подсовывать сразу Records из функции. Поэтому родилась теория, что функция возвращает на стеке метабалицу с __call в пустоту.
Потом стал экспериментировать дальше и выяснилось, что даже и сам объект под for получается в пустоте. Т.е. - вообще любая попытка в for подсунуть что-либо не выделенное явно, а возвращаемое функцией - убивает родителя.
Не знаю. Ей-богу, даже не парился бы с разбирательствами причин. Раз оно проявляется однозначно при определенных обстоятельствах - тупо избегай такие обстоятельства и вся недолга. Никакой проблемы не вижу.
Модуль: Form: (2) [Conversion01]
Строка 114: attempt to call global 'pair' (a nil value)
Стек вызовов:
Form: (2) [Conversion01] :114: in function <at string:114>
Form: (2) [Conversion01] :119: in function <at string:93>
Form: (2) [Conversion01] :183: in function 'ReReadSimpleConvForTransfer2'
Form: (2) [Conversion01] :859: in function <at string:857>
local base=CroApp.GetBank():GetVocabulary():GetBase("XX")
if base then for r in (function(R) if R then
R:Sort{{field=5,descent=true},{field=7},{field=10}} -- Sort return nil али R али ??
return R.Records -- оно крякает как итератор?
end return pairs({}) -- for'у потребен итератор
end)(base.RecordSet)
do arrSimpleConv[#arrSimpleConv+1]={Type=r:GetValue(5),
LegName=r:GetValue(10),
PickName=r:GetValue(11),
Rules = (function(iiter) local res={}
for i,p in iiter
do res[i]=table.unserialize(p)end
return res
end)(ipairs(r:GetValue(20, 0))),
FlagHierarch=tonumber(r:GetValue(30)),
}
end end
Правда там у них 7.0, а у меня сейчас купленное за денежки ещё 6.3 - могло что-то измениться.
Например вот такое может быть интересно, как мне кажется:
Метод Sort выполняет сортировку записей, входящих в набор.
bool <RecordSet object>:Sort ( table sortConditions1 [, table sortConditions2] .... [, table sortConditionsN ] )
...
Примечания
...
После сортировки набор может занимать значительно больше места в памяти, нежели до нее
интересно увидеть исходно ваш код с использованным уместно функ-литералом с вызовом на месте. — ака вычисляемое выражение с побочками(т.е оборачивание императива в одежды вычисляемого в месте упоминания - а не задекларированного «где-то ранее» али использование временной памяти) - всё просто. - в Lua лямбды честнее python’их судя по ….
Ничего в голову не приходит, кроме, возможно, callback'ов в JavaScript. Вон на knockoutjs нашел кусочек у себя - колбэк на колбэке и оба внутри колбэка. И даже не слишком тошно выглядит, вроде.
На Lua дальше утилитарных задач в Кроносе «в лоб» ничего не делал, и придумать искусственно пока не могу где бы это было однозначно уместно, и чтоб не выглядело как чистый выпендрёж ради выпендрёжа.
По-моему чтобы такие штуки честно использовать нужно очень чётко представлять, что в машине творится в это время. Сами кишки языка должны быть понятны. А сейчас всё так сложно стало, что даже сам процессор-то не знает сколько тактов на инструкцию потратит. В былые годы на УАЗике ездил - передачи без сцепления переключал, потому что слышал и понимал в каком положении шестеренки в коробке крутятся. Нынче и сцепления-то нет у водителя - ехаем и чудненько.
Оператор GOTO нарушает обратную совместимость между версиями.
Ты о чём?
О том, что до 5.3 Оператора GOTO не было, а потом появился. Брейки делать стало проще в циклах (гыгыгы), и переводить старый код на новую Луа немножко веселее.
Ну а то, что ты про метатаблицы написал, я конечно осилю если прям уж постараюсь, но вопрос зачем мне это? Lua быстрый и на этом все. Возьму тогда уж лучше один из си-подобных скриптов с типами, скоростью и упрощенным сишным синтаксисом.
local rst = (function(base) if base then
local R = base.RecordSet -- ? всегда не пуст по API?
R:Sort{{field=5,descent=true},{field=7},{field=10}}
return R
end return {Records:pairs({})} end)(CroApp.GetBank():GetVocabulary():GetBase("XX"))
for r in rst.Records do
arrSimpleConv[#arrSimpleConv+1]={Type=r:GetValue(5),
LegName=r:GetValue(10),
PickName=r:GetValue(11),
Rules = (function() local res={}
for i,p in ipairs(r:GetValue(20, 0))
do res[i]=table.unserialize(p)end
return res
end)(),
FlagHierarch=tonumber(r:GetValue(30)),
}
end
Обратная совместимость была бы сломана, если бы goto был, а потом его убрали, либо если бы изменилось его поведение. Тут же его добавили, но код без goto из-за его введения никак не сломался.
Обратная совместимость в Lua ломалась не раз, но из-за других вещей (и это не настолько большая проблема, как думают люди со стороны).
Не то, чтобы по API. Просто именно для базы ХХ мы точно знаем, что в ней есть записи. Если другой программист не увидит это место - можно не проверять её. Мы ж уверенны, что раз есть ХХ, то в ней точно есть набор записей. В общем случае, конечно, надо проверять.
Для упрощения проверки именно проблемы в невозможности использовать анонимную функцию в for - и эту проверку, и сортировку можно убрать точно. Если без локальной переменной rst, сразу в for - крашится с первого раза.
Мы ходим по кругу. Вроде как устаканили этот вопрос уже.
-------------------------------------------------
вопрос в использовании(уместном) «императивных выражений»
Вы меня окончательно запутали жонглированием терминами.
Так:
DEF SEG = varseg(tmp(0))
poke varptr(tmp(0))+0,&h90
poke varptr(tmp(0))+1,&hb8
/*-- отрезал для примера --*/
poke varptr(tmp(0))+36,&hea
poke varptr(tmp(0))+37,&hcb
Label = varptr(tmp(0))+1
call absolute Label
DEF SEG
out &h3ce,5
out &h3cf,0
литеральная форма функции в месте её единичного вызова
Rules = (function() local res={}
for i,p in ipairs(r:GetValue(20, 0))
do res[i]=table.unserialize(p)end
return res
end)(),
т.е в заполнении данных допустимы не только инфиксные и унарные(включая вызовы функций) при построении «экспрешен'ов» но и вычислениеисполнение(с возможными побочками) любого(почти) луа блока обёрнутого в (function() ... end)()
т.е если луа действительно вырос через язык конфиг-файлов - то вот такая возможность по месту выставить поле - вычислениемисполнением произвольного кода из операторов.
одна из нескольких фич которую слабо в туториалах посвещённых по сути ваще обучению программированию ( в отличии от фич языка) касаются
перечитывая про терру pldi071-devito.pdf сдаётся мне что ты изобретаешь метастадийные quote скобки через обёрнутые лямбды по месту. вообще, там операционная семантика луа и терры и связки многостадийной луа/терра указана. пример объектной системы про orion dsl:
We measured the overhead of function invocation in our implementation using a micro-benchmark and found it performed within 1% of analogous C++ code. The implementation requires only 250 lines of Terra code to provide much of the functionality of Java’s class system. Users are not limited to using any particular class system or implementation.
занятный такой троллейбус из буханки – метастадийный типа MetaOcaml, только Lua + LLVM + C FFI.
Что лишний раз подтверждает что ты глупый. Ригидное мышление. Вбил себе в маленькую головенку один язык, пытаешься выучить отличающийся от него достаточно сильно Lua и полученные знания тебе мешают. Так бывает, не расстраивайся. Сделать ты ничего не можешь, но глупость свою лучше все-таки скрывай. Незачем на язык валить, все равно не поверят.
На работе в Ц++ проект встраивали Луа и Питон. Луа легче и проще встраивается, меньше проблем с потоками, меньше проблем с сопровождением, лучше управляется из приложения.
У Питона главный плюс в том что его знает каждая собака.
О том, что до 5.3 Оператора GOTO не было, а потом появился. Брейки делать стало проще в циклах (гыгыгы), и переводить старый код на новую Луа немножко веселее
local s = {}; local c = 0;
for i = 3, n, 2 do
c = c + 1
s[c] = i
end
то сразу time execute уменьшается с 36 до 25 секунд на моей машине. (Под рукой пока только Astra и её lua5.3. Дома проверю ещё на более другой машине)
Это я постеснялся у господина qulinxao3 уточнять про его [#arrSimpleConv+1].
Честно - не знаю, как это # устроено точно. Но полагаю оно тупо каждый раз считает с самого начала. Если таблица будет достаточно большая такое вот #arrSimpleConv в конце концов может стоить времени исполнения всего остального кода. Это ж вроде много в каких языках так.
Для lua 5.4 это не работает. Хоть руками, хоть решеткой - никакой разницы. (на этой машине получилось около 12 секунд в обоих случаях)
Только для lua 5.3 - в два раза быстрее получается, если все решетки считать самостоятельно в локальных переменных. (на этой машине получилось ~48 против ~20 секунд)