将序列化数据加载到表中

时间:2011-05-11 03:12:12

标签: serialization lua deserialization

对于答案to another question,我想将一些序列化的lua代码加载到表中。要加载的字符串是这种形式:

SavedVars = {  }
SavedStats = {  }

(其中每个{...}可能是任何Lua表达式,包括具有嵌套数据的表构造函数。我假设它不调用任何(全局)函数或使用全局变量。

我最终想要的是这种形式的表格:

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

之后我不希望有全局变量SavedVars。 如何最优雅地做到这一点?

(我已经找到了解决方案,但也许有人有更好的解决方案。)

1 个答案:

答案 0 :(得分:4)

这是我的解决方案:

-- 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将函数的全局环境修改为新表。然后调用加载的函数一次填充此表(而不是全局环境),然后我们可以返回。

将环境设置为新表会导致代码根本无法使用任何全局数据。我认为这是沙箱代码的一种好方法,但是如果不需要,你可以在之前填充表格或者提供一些metatable(但在返回表格之前取消设置)。

此加载功能也适用于Saving Tables with Cycles中生成的序列化数据。