lua-users home
lua-l archive

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


> One other thing you might want to think about is
> a naming convention for fields to keep them from
> being persisted. For example, one could specify
> that fields starting with "t_" were transient
> and not to be persisted.
>
> Mark

IMHO a naming convention is a perfect opportunity for surprising users and
creating code maintenance problems (consider the impact of a decision to
change whether a member is persisted or not).

Far simpler would be to state that whatever object is returned by the
__persist metamethod (provided that method is a function) is persisted in
the object's place.  So if certain members of a Lua table should not be
persisted then __persist can be trivially written to return a new table that
is a copy of the original without the "transient" members.  Or perhaps it
could just contain a table/list of the keys corresponding to members of the
original object that should be persisted (or that shouldn't be persisted,
and maybe a flag to distinguish which it is).  However, IMHO this isn't
worth the effort in code or usage documentation.  In fact my recommendation
of accepting "whatever object is returned by the __persist metamethod"
probably isn't worth it.

Why?  Simple the Lua code difference between Ben's previous design statement
that __persist should return a closure and my statement that it could return
"whatever" is trivial.  For instance...

-- Returning a "stand-in" table
mt.__persist = function(tbl) do
   local newtbl = {x=tbl.x, y=tbl.y, z=tbl.z}
   return newtbl
end

-- Returning a closure
mt.__persist = function(tbl) do
   local newtbl = {x=tbl.x, y=tbl.y, z=tbl.z}
   return function() do return newtbl end
end

-- Providing a list of members to persist
mt.__persist = {"x", "y", "z"}

-- Providing a list of members to NOT persist
mt.__persist = {"a", "b", "c", exclude=true}

--------
The difference between all of these is pretty minimal.  The non-function
versions are in fact slightly simpler, but very limited in functionality.

In fact the only real "complexity"/"gotcha" here is that the following
version of "Returning a closure" is VERY WRONG

-- Returning a closure (INCORRECTLY)
-- This will force tbl itself to be persisted
-- in the stream
mt.__persist = function(tbl) do
   return function() do
      return {x=tbl.x, y=tbl.y, z=tbl.z}
   end
end