Модуль сереализации/десереализации и печати таблиц Lua

Автор записи: TGB
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 16, среднее: 2,81 из 5)
Загрузка...

Сереализация таблицы Lua (со всеми ее, возможно, многоуровневыми вложенностями и перекрестными ссылками) это представление ее в виде строки. Десереализация это обратная операция – восстановление таблицы из строки.

Эти операции могут потребоваться, например, при хранении таблиц на внешнем накопителе или при передачи таблиц между различными скриптами.

Особенность представленного модуля состоит в том, что на вид сереализуемых/десереализуемых таблиц накладываются более слабые ограничения, чем это обычно принято.

--

В модуле реализовано два варианта сереализации/десереализации таблиц Lua:

1) Сереализация/десереализация (функции tbl_to_string и string_to_tbl) таблиц частного вида со следующими ограничениями:

- ключи и поля таблицы только типа : table (простые, не метатаблицы), booleannumberstring;

- все внутренние элементы таблицы (ключи и поля) типа table (ссылки на них) должны быть уникальными (в пределах таблицы с учетом всех ее вложенностей).

2) Сереализация/десереализация (функции tbl_to_str  и str_to_tb ) таблиц общего вида (при условиях,  детально рассмотренных далее в описании модуля), элементами (ключами и полями) которых могут быть любые Lua-типы (включая метатаблицы и ссылки на functionthread, userdata). Связи между элементами таблиц могут быть произвольными.

Кроме того, в модуле реализована функция печати любых Lua-данных, в том числе произвольных таблиц в удобном для анализа виде (со всеми вложенностями и перекрестными связями, включая метатаблицы, а также ссылки на functionthread, userdata).

----

В представленном скрипте-тесте выполняется сереализация/десереализация глобальной таблицы Lua _G, хранящей стандартные и подключаемые пакеты скрипта, все его переменные без спецификации local и т.д. Там же приведены примеры  сереализации/десереализации более простых таблиц, например:

local t1 = {5, 't1'}

local tbl_str = {1, 2

, { 3, 4, {5}, [t1] = '[t1]' }

, [ { {}, '[8]' } ] = {'Простой пример'}

}

------------------------------------------------------

Реализовать сереализацию/десереализацию таблиц частного вида просто.

Реализация сереализация/десереализация таблиц общего вида это более сложный вариант. Ниже приводится краткое описание такой реализации.

В функции сереализации таблиц общего вида выполняется рекурсивный проход по всем элементам таблицы с ключами и полями произвольного lua-типа. При этом создается код Lua-скрипта (в виде текста скрипта или байт-кода), выполнение которого, с использованием данных, созданных для него, обеспечивает полное восстановление любой сереализованной таблицы в выполняемом скрипте или при его перезапуске.

Функция десереализации таблиц запускает сформированный при сереализации Lua-код, полностью восстанавливающий (с учетом всех вложенностей таблицы произвольного вида) все элементы типа booleannumberstringtable (в том числе метатаблицы).  Кроме того эта функция, используя данные сереализации, восстанавливает также ссылочные элементы таблицы типа functionthread и userdata.

  Существенным условием возможности восстановления в предложенном модуле ссылочных элементов таблицы явлается: десереализация в том же контексте (это понятие определено далее), в котором была выполнена сереализация. При отсутствии в таблице ссылочных элементов, никаких ограничений на выполнение десереализации нет.

---

  В эффективности выполнения функций сереализации/десереализации таблиц общего вида можно убедиться, запуская на исполнение приведенный в статье пример сереализации/десереализации глобальной таблицы Lua _GВ моем случае тестирования модуля в «песочнице» QUIK,  сереализация  _G (при распечатывании всех ее вложенностей это ~360 строк) выполняется за ~2 млсек., а десереализация за ~1 млсек. Длительность выполнения операций сереализации/десереализации в модуле пропорциональна размеру обрабатываемых таблиц и, практически, не зависит от степени их сложности.

-----

Описание модуля

В подавляющем большинстве случаев применения сереализации/десереализации таблиц, функциональности простых функций tbl_to_string и string_to_tbl, наверное, достаточно.

---

Во всех случаях применения простых функций, их можно заменить, без потери простоты использования и эффективности, на более общие функции tbl_to_str  и str_to_tblВ области общей применимости, некоторым преимуществом простых функций, является представление строкой – результатом функции tbl_to_string сереализованной таблицы в наглядной, скобочной форме конструктора таблиц Lua. Но не все таблицы без ссылочных данных могут быть обработаны простыми функциями (ограничение на вид допустимых таблиц было описано ранее). Общие функции могут обрабатывать любые такие таблицы.

---

При использовании tbl_to_str  и str_to_tbl для сереализации/десереализации таблиц  со ссылочными данными, важным понятием является контекст выполнения сереализации/десереализации таблиц.

Под контекстом выполнения сереализации/десереализации функций tbl_to_str  и str_to_tbl понимается список доступных им, в момент их выполнения, ссылочных данных (functionthread и userdata), на которые есть ссылки из сереализуемой таблицы и из переменных скрипта вне этой таблицы. Если упрощенно: десереализация должна выполняться в том скрипте (возможно, перезапущенном), в котором была выполнена сереализация. Из ранее сказанного следует, что, если в сереализуемой таблице есть ссылочное данное, на которое нет ссылок из других, доступных скрипту, переменных, то это данное, при десереализации, восстановить нельзя. Но зная об этом, избежать такой ситуации можно, специально создавая в скрипте ссылки в переменных(или таблицах), внешних  относительно сереализуемой таблицы.

В простом варианте контекстом может быть любая таблица, внешняя по отношению к сереализируемой, внутри которой, на любом ее уровне вложенности, хранятся ссылки на ссылочные данные, на которые есть ссылки и из сереализируемой таблицы. Для более сложных случаев можно использовать функцию формирования контекста сереализаци/десереализаци creating_link_tables.

В модуле контекстом по умолчанию (изменяемым при необходимости) является таблица, ссылка на которую хранится в _ENV (переменная окружения скрипта для версий Lua >= 5.2), с добавлением к этой таблицы области всех локальных переменных скрипта, видимых в месте сереализации/десереализации таблицы.

---

Параметры и результаты всех функций модуля описаны в комментариях их кодов. При этом в квадратных скобках указаны необязательные параметры, задания которых в типичных случаях не требуется.

-----------

Использование функций сереализации/десереализации таблиц Lua общего вида

В простом варианте восстановления сереализованной таблицы после перезапуска скрипта, когда контекст ее десереализации не отличается от контекста ее сереализации (в коде перезапускаемого скрипта нет изменений , либо эти изменения не затрагивают контекст десереализации), все просто.

-- Сереализация  таблицы --

< Строка образа таблицы >  = tbl_to_str (<Таблица> [, <Формат образа таблицы> [ ,<Контекст сереализации>]])

Где:

<Строка образа таблицы> - если же 2-ой параметр путь файла, то запись строки в файл;

<Формат образа таблицы> - путь файла сохранения образа (в виде строки) или вид результата (0 | 1 - строка-скрипт или байт-код);

<Контекст сереализации> - таблица контекста работающего скрипта (например, _G).

-- !! Далее может быть перезапуск скрипта  --

-- Восстановление таблицы --

<Таблица> = str_to_tbl (<Сохраненный где то образ - результат функции tbl_to_str > [,<Контекст сереализации>])

--

Более сложный вариант использования модуля (при отличии контекста восстановления таблицы от контекста ее сереализации)  в некоторых случаях возможен, но в статье не описывается.

------------------------------------------------

Далее приведены код модуля сереализации/десереализации таблиц Lua и код скрипта , тестирующий этот модуль .  Для подключения модуля к коду теста, достаточно поместить файл кода модуля (под именем файла: table_serialization_all.lua) в папку хранения кода запуска КВИКа: info.exe.  По ссылке: https://cloud.mail.ru/public/W7E8/uR8ik7X9Z   лежат коды.

Скрытый текст
Скрытый текст

Добавить комментарий

Модуль сереализации/десереализации и печати таблиц Lua: 1 комментарий

  1. За каждую очередную свою статью на сайте, я, в качестве оценки, получаю от кого-то очередной кол . Похоже на то, что это один и тот же. «Разнести» в пух и прах содержи-мое статьи в комментариях слабо?
    Наверное, я как то сильно «защемил» чье-то мелко-мстительное самолюбие, и кол это все, что от него осталось .