Вот мое решение:
-- 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
, чтобы изменить глобальную среду функции для новой таблицы. Затем вызов загруженной функции один раз заполняет эту таблицу (вместо глобальной среды), которую мы затем можем вернуть.
Установка среды для новой таблицы приводит к тому, что код вообще не может использовать глобальные данные. Я думаю, что это хороший способ для песочницы кода, но если он не нужен, вы могли бы заполнить таблицу раньше или предоставить некоторую метатабильную (но сбросить ее перед возвратом таблицы).
Эта функция загрузки также будет работать с сериализованными данными, полученными как в Сохранение таблиц с циклами .