lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


A bit of historical perspective:

When I originally designed Pluto, although I considered the
possibility of serializing the globals table, it was my feeling that
people wouldn't normally do it. This was partially because my
preferred coding style with Lua tended to keep things out of the
global scope, and partially because I felt that if one was serializing
such a huge amount of the Lua space, a solution like lper (which, BTW,
is awesome and deserves to be updated and used more) would be a better
fit.

My "solution" for persisting the global table, then, was a lazy one:
Someone who wished to persist the globals table would do so by putting
a whole bunch of stuff in the permanents table... basically, every
library and global function that shouldn't be messed with. The globals
table would then be serialized, either directly or in a location
directly accessible from the serialized object. Then on reload, the
reloaded table (not yet the globals table) would be reintegrated into
the real globals table through a simple "for k,v in pairs(t) do
_G[k]=v end". This isn't a perfect approach, as _G itself could be
held as a reference by an object, and on unserialize this would then
point to the not-the-global-table result. Normally one would deal with
this by keeping such an object in the permanents table, but in this
instance of course that wouldn't work, as _G needs specifically to NOT
be a permanent object. Other than that caveat, however, this approach
should work fine.

If you want, it shouldn't be too hard to mung Pluto up a bit to make
it write its rebuilt data directly into the REAL globals table, rather
than into a nwely crated table. That would fix the caveat above, and
remove the need for the shallow copy. (You'd still have to shove a
bunch of stuff into a permanents table, to keep Pluto away from your
C-functions.) Of course, this would only work if you were specifically
serializing the globals table as the primary object.


For your second need, it seems like the laziest solution would be to
put the onus on maintaining changes from the pristine to the maculate
table on the table itself. This is a common thing to do with Pluto,
with __index and __newindex metamethods capable of delegating to the
pristine table for unchanged values, and the table itself for changes
(including, and this is an important problem, values which have been
set to nil). Then there's nothing special about serializing it, not
even a need for a __persist metamethod -- just stick the pristine
table in the permanents.

On Thu, Oct 8, 2009 at 9:52 AM, Duncan Cross <duncan.cross@gmail.com> wrote:
> Another subtle thing to watch out for is that, if you want to
> serialize the global variable scope, it is easy to forget about the
> string metatable which will still have its __index field set to the
> *old* string table - so if you add custom functions to string, and
> want to call them as methods, they seem to disappear after
> serialization and deserializatin. The solution is to serialize not the
> global variable scope itself but a temporary table that contains it,
> as well as the string metatable, and possibly other base-type
> metatables if you have set them.

Huh, yikes.

Ben