• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Для новичков

glonium

New member
еще замечу что namespace это из другого языка , например C#, луа нет такого понятия.
Возможно поэтому Вы и не поним
"Пространство имён" это термин не относиться к конкретному языку программирования.
Вот например Пространство имён (программирование) — Википедия
 

glonium

New member
Да, и можно вопрос а где можно почитать что по капотом виртуалки lua?
 

nikolz

Well-known member
выигрыша не будет никакого.
Полагаю, что этот фарш есть авторское решение (поделка) замены понятия модуля в луа на основе dofile.
Может быть сначала изучить возможности луа?
 

nikolz

Well-known member
От лица автора разрешите поинтересоваться, по сравнению с чем выйгрыша не будет и почему?
---------------------
попробую объяснить.
--------------------------------
Вы пытаетесь создать механизм формальных параметров для оператора dofile.
Но это решается механизмом модулей(библиотек).
Механизм dofile - это аналог макроса include в C.
Т е это механизм вставки чанка в текст программы.
----------------------
По-моему мнению программирование для задач реального времени ( а контроллеры именно для таких задач и используются) требуют совершенно другого подхода по сравнению с рассчтеными задачами на компе. Более того реалтайм задачи на луа на ESP очень отличаются от подобных задач на компе.
-----------------------
Поэтому оптимальным решением передачи параметров в dofile - это передача через глобальную таблицу, в которой будет создана и Ваша таблица стека, в которую Вы будете записывать передаваемые параметры.
------------------------
Более того, использование передачи параметров через глобальную таблицу и dofile позволяет снять ограничения на размер кода программ (количество вызовов dofile фрагментов)
При этом нет никаких дополнительных затрат на создание искусственно надуманного механизма "аля параметры функции".
------------------------------
Если же хочется использовать механизм формальных параметров,
то есть механизм модулей, что позволяет работать с библиотекой полноценных функций.
----------------------------
примерно так.
-
 

nikolz

Well-known member
и еще замечу, что это
function call(file,p)
if (call_stack==nil) then
call_stack={}
end
table.insert(call_stack,args)
args=p
local res=dofile(file)
args=table.remove(call_stack)
return res
end

будет в глобальной таблице и в куче всегда.
там же будет и таблица call_stack
--------------------------
а этот оператор:
ocal r=call("call1.lua","parametrs for call1.lua")
сначала запишет хеш "parametrs for call1.lua" в ваш стек через вызов вашей функции
--------------------------------
Т е ваше решение - это траты память и времени процессора лишь для создания удобства не следить за использованием имен переменных.
 

nikolz

Well-known member
и еще в реал тайме надо в цикле исполнять некоторый блок меняя у него некоторые параметры
В Вашем варианте внешние переменные для dofile придется хранить и в глобальной и в вашей таблице. Т е памяти на них потребуется два раза больше.
 

glonium

New member
Но это решается механизмом модулей(библиотек).
Я так не думаю, ведь модуль не что иное как глобальная таблица.
Механизм dofile - это аналог макроса include в C.
Это тоже я думаю неверное утверждение, в C компоновщик собирает всё в один файл и ДИРЕКТИВОЙ [HASHTAG]#include[/HASHTAG] в файл просто вставляется код из другого файла, указанного в [HASHTAG]#include[/HASHTAG]. Тогда как dofile освобождает память от предыдущего скрипта и загружает в память скрипта новый.

По-моему мнению программирование для задач реального времени ( а контроллеры именно для таких задач и используются) требуют совершенно другого подхода по сравнению с рассчтеными задачами на компе. Более того реалтайм задачи на луа на ESP очень отличаются от подобных задач на компе.
1) Контроллеры не всегда используются в составе СРВ
2) Стек протоколов TCP IP не может быть использован в системе реального времени так не гарантировано время передачи телеграммы по сети
3) Lua тоже не гарантирует вам постоянного времени оклика на события таймера так как таймер работает по callback вызову, а если исполняется ваш код и произошло событие таймера, то callback будет вызван по завершению вашего кода.
Итого Nodemcu проблематично использовать в СРВ
(Система реального времени — Википедия)
Более того, использование передачи параметров через глобальную таблицу и dofile позволяет снять ограничения на размер кода программ (количество вызовов dofile фрагментов)
При этом нет никаких дополнительных затрат на создание искусственно надуманного механизма "аля параметры функции".
call это обёртка для dofile, поэтому она полностью сохраняет механизм dofile
и еще замечу, что это
function call(file,p)
if (call_stack==nil) then
call_stack={}
end
table.insert(call_stack,args)
args=p
local res=dofile(file)
args=table.remove(call_stack)
return res
end

будет в глобальной таблице и в куче всегда.
там же будет и таблица call_stack
Так задумана эта небольшая плата за чистый GLOBAL

и еще в реал тайме надо в цикле исполнять некоторый блок меняя у него некоторые параметры
В Вашем варианте внешние переменные для dofile придется хранить и в глобальной и в вашей таблице. Т е памяти на них потребуется два раза больше.
1) Всегда можно избежать использование глобальных переменных
2) если переменные сложные таблицы или строки, тогда при операции приравнивание копируется только ссылка на данные так что не в 2 раза в основном.
 

nikolz

Well-known member
glonium,
Я уже понял, что Вы все строите на собственном думанье, но без углубления в существо вопроса.
Где Вы прочитали, что модуль - это глобальная таблица?
----------------------------------
Я вам рассказываю свой опыт,знания и результаты измерений,
Вы мне свои думы и рассуждения на "кофейной гуще".
---------------------
Даже нет желания объяснять Вам.
Вы опять что-либо придумаете .
Почитайте документацию на луа, пожалуйста.
---------------------------
 

glonium

New member
Гнилой базар какой-то, по существу , Вы можете сравнить показания heap() или нет?
В моём случае чуть больше расход на размер фунции и стека вызовов, это понятно но вопрос в том, что это избавляет от необходимости массово клепать глобальные переменные
 

nikolz

Well-known member
В моём случае чуть больше расход на размер фунции и стека вызовов, это понятно но вопрос в том, что это избавляет от необходимости массово клепать глобальные переменные
------------------------------------
В Вашем случае Вы изобретаете то, что уже сделано в луа.
Типа "пусть труба пониже и дым пожиже, но свое"
----------------------------
Если хотите городить свой огород - вольному воля, а ... рай.
----------------------------------
Попробуйте для начала придумать задачу на ESP,
где надо " массово клепать глобальные переменные"
--------------------------------------
Если сможете придумать,
то решите ее с использованием модуля,
глобальных переменных
и вашего предложения.
При этом , в своем варианте еще решите задачу возврата результата из функций, которые в dofile.
И попробуйте решить задачу с множеством функций внутри файла и их вызовом из главной программы.
Успехов в изучении луа.
 

glonium

New member
Вы можете тогда объяснить популярно я нашел только инфу что модули грузяться напрямую в оперативную память, тогда как dofile выгружает текущий скрипт и загружает указанный. Вопросы: 1) Как работает механизм загрузки модулей, и как их потом выгружать. 2) Куча и память в которой лежит исполняющийся скрипт это одно и то же. 3) при обрашении к функции модуля выгружается ли текущий код из памяти?
 

glonium

New member
Не что такое nil а чему его прировнять чтобы модуль выгрузить я знаю что такое nil
 

nikolz

Well-known member
Вы можете тогда объяснить популярно я нашел только инфу что модули грузяться напрямую в оперативную память, тогда как dofile выгружает текущий скрипт и загружает указанный. Вопросы: 1) Как работает механизм загрузки модулей, и как их потом выгружать. 2) Куча и память в которой лежит исполняющийся скрипт это одно и то же. 3) при обрашении к функции модуля выгружается ли текущий код из памяти?
---------------------
Попробую объяснить популярно. Для этого придется кое-что упростить.
Если Вы владеете СИ, то механизм создания модулей и их загрузка можно хорошо изучить в API С for LUA
Популярно.
модуль - это таблица (типа как у Вас стек).
В эту таблицу помещаются указатели на функции модуля и переменные модуля (ну типа namespace,только namespece понятие для трансляторов ) а таблица - это реально существующая область памяти .
Указатель на модуль помещается в глобальную таблицу.
когда мы загружаем модуль оператором require(), то проверяется есть ли этот модуль и если его нет то он транслируется и размещается в стеке луа в глобальной таблице под именем файла модуля.
----------------------
после этого мы может обратится к любой функции в модуле записав
параметры_выхода=имя_файла.имя_функции(параметры входа)
-----------------
dofile отличается тем что он загружает кусок кода оформляет его как чанк и исполняет.
----------------------
Примерно так.
 

nikolz

Well-known member
Не что такое nil а чему его прировнять чтобы модуль выгрузить я знаю что такое nil
Чтобы выгрузить модуль надо освободить область памяти в которой его таблица.
Для этого надо в глобальную таблицу на место хранения модуля запись nil.
После этого желательно явно вызвать сборщик мусора, иначе память не освободится, пока вм луа не вызовет сборщик.
 

nikolz

Well-known member
Так ка ВМ ЛУА выполняет скрипт в оперативной памяти (но встроенные функции размещены во флеш)
то для работы с большими программа надо разбивать их на фрагменты и выполнять как dofile.
Я писал об этом статью на хабре и приводил пример на этом форуме.
Если будете делать как я написал, то объем оперативной памяти не будет проблемой.
 

glonium

New member
Да вот хотелось бы заменить dofile на requvire. Правильно ли понимаю для выгрузки модуля надо packedge.loaded[name]=nil? Память для переменных и скрипта это одна и та же память или это две разных области? То есть VM Lua и скрипт и переменные в heap сохраняет?
 

nikolz

Well-known member
Да вот хотелось бы заменить dofile на requvire. Правильно ли понимаю для выгрузки модуля надо packedge.loaded[name]=nil? Память для переменных и скрипта это одна и та же память или это две разных области? То есть VM Lua и скрипт и переменные в heap сохраняет?
--------------------
Хотел бы обратить внимание на один из плюсов LUA.
Это возможность отладки алгоритмов вне железа на котором потом исполняем.
--------------------------
Поэтому предлагаю Вам самостоятельно попробовать ответить на свои вопросы.
Для этого надо установить редактор текста SCITE. Он тоже написан на луа.
В нем есть возможность запускать скрипты на луа на исполнение.
Т е напишите модуль с функций.
напишите тест в котором сначала загружаете модуль и исполняете функцию потом уничтожаете модуль и пытаетесь снова вызвать
Ну и т д
------------------------
В частности глобальная таблица называется _G
например можно записать так
x=1
а можно так
_G["x"]=1
а можно так
_G.x=1
 

glonium

New member
Да я отлаживал на компе у меня ubuntu, поэтомя я пользовал gedit+lua, но на большой машине с памятью не так все просто она выделяется страницами по мере надобности интерпритатору, если нехватает ему в ход идет файл подкачки поэтому очень трудно уловить размер heap он постоянно меняется по мере необходимости.
 
Сверху Снизу