загрузка сериализованных данных в таблицу - PullRequest
1 голос
/ 11 мая 2011

Для ответа на другой вопрос я хотел загрузить сериализованный код lua в таблицу. Загружаемая строка имеет следующую форму:

SavedVars = {  }
SavedStats = {  }

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

В конце концов я хочу получить таблицу такого вида:

{ ["SavedVar"] = { }, ["SavedStats"] = { } }

Я не хочу иметь глобальные переменные SavedVars впоследствии. Как это сделать максимально элегантно?

(Я уже нашел решение, но, возможно, у кого-то есть лучшее.)

1 Ответ

4 голосов
/ 11 мая 2011

Вот мое решение:

-- loads a string to a table.
--   this executes the string with the environment of a new table, and then
--   returns the table.
--
-- The code in the string should not need any variables it does not declare itself,
-- as these are not available on runtime. It runs in a really empty environment.
function loadTable(data)
   local table = {}
   local f = assert(loadstring(data))
   setfenv(f, table)
   f()
   return table
end

Загружает строку данных с помощью loadstring, а затем использует setfenv, чтобы изменить глобальную среду функции для новой таблицы. Затем вызов загруженной функции один раз заполняет эту таблицу (вместо глобальной среды), которую мы затем можем вернуть.

Установка среды для новой таблицы приводит к тому, что код вообще не может использовать глобальные данные. Я думаю, что это хороший способ для песочницы кода, но если он не нужен, вы могли бы заполнить таблицу раньше или предоставить некоторую метатабильную (но сбросить ее перед возвратом таблицы).

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

...