lua-users home
lua-l archive

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

So i found instead of lua Pickle, and it supports saving functions which is great.

It did bring to light a bug though... at least on my windows vista machine.

It seems that stdio tmpfile() used by io.tmpfile() has been depricated because of security reasons.

On Sat, Jan 23, 2010 at 8:33 PM, Joe Andresen <> wrote:
Sorry for the email spam, but i thought the output of the pickle function might help ( and the error)... It's actually unpickle that is breaking with the error.

the dofile in unpickle complains about a symbol at eof.
i understand that the end of the file is malformed, but why would loadstring and gentables() work and not dofile?

here is the file.

return {
["a b"]="zzz",

On Sat, Jan 23, 2010 at 8:30 PM, Joe Andresen <> wrote:
I seem to be having a problem with the changes I made to Pickle to write to a file.

the fundamental difference is i use dofile instead of gentables = loadstring(s) and t = gentables().

can someone explain the difference and why dofile might not work?

Here is my code below :
-- Pickle.lua
-- A table serialization utility for lua
-- Steve Dekorte,, Apr 2000
-- Edited by: Joe Andresen, Jan 2010
-- Freeware

function pickle(t, filename)
  return Pickle:clone():pickle_(t,filename)

Pickle = {
  clone = function (t) local nt={}; for i, v in pairs(t) do nt[i]=v end return nt end 

function Pickle:pickle_(root, filename)
  if string.find(filename, ".lua") then 
    io.output(filename, "w" )
    filename = filename .. ".lua"
  if type(root) ~= "table" then 
    error("can only pickle tables, not ".. type(root).."s")
    return false
  self._tableToRef = {}
  self._refToTable = {}
  local savecount = 0
  local s = ""

  while table.getn(self._refToTable) > savecount do
    savecount = savecount + 1
    local t = self._refToTable[savecount]
    s = s.."{\n"
    for i, v in pairs(t) do
        s = string.format("%s[%s]=%s,\n", s, self:value_(i), self:value_(v))
    s = s.."},\n"
  string.format("{%s}", s)
  io.write("return ",s)
  return true

function Pickle:value_(v)
  local vtype = type(v)
  if     vtype == "string" then return string.format("%q", v)
  elseif vtype == "number" then return v
  elseif vtype == "table" then return "{"..self:ref_(v).."}"
  else --error("pickle a "..type(v).." is not supported")

function Pickle:ref_(t)
  local ref = self._tableToRef[t]
  if not ref then 
    if t == self then error("can't pickle the pickle class") end
    table.insert(self._refToTable, t)
    ref = table.getn(self._refToTable)
    self._tableToRef[t] = ref
  return ref

-- unpickle

function unpickle(filename)
  --if type(s) ~= "string" then
  --  error("can't unpickle a "..type(s)..", only strings")
  local tables = dofile(filename)
  --local tables = gentables()
  for tnum = 1, table.getn(tables) do
    local t = tables[tnum]
    local tcopy = {}; for i, v in pairs(t) do tcopy[i] = v end
    for i, v in pairs(tcopy) do
      local ni, nv
      if type(i) == "table" then ni = tables[i[1]] else ni = i end
      if type(v) == "table" then nv = tables[v[1]] else nv = v end
      t[ni] = nv
  return tables[1]

function test()
  local t = {
    name = "foo", 
    contact = { phone = "555-1\r\n212", email = ""},
  t.t = { 1 } = t
  t["a b"] = "zzz"
  t[10] = 11
  t[t] = 5
  t[t.t] = 10

  local s = pickle(t, "thing.lua") 

  local ut = unpickle("thing.lua") 
print("pickled string:\n\n"..pickle( ut ))
  print("loop test:   "); eq(ut ==
  print("subitem test:"); eq( ==
  print("number value:"); eq(ut.ssn == t.ssn)
  print("number index:"); eq(ut[10] == 11)
  print("table index: "); eq(ut[ut] == 5)

function eq(b)
  if b then print(" succeeded") else print(" failed") end



On Sat, Jan 23, 2010 at 11:23 AM, Andre Leiradella <> wrote:
Oops, I should've taken a closer look at the code. Sorry.

Check Joe Andresen's post in this topic, it has an easier solution.

On 23/01/2010 13:52, Florian Weimer wrote:
* Andre Leiradella:

       clone = function (t) local nt={}; system_lib.for_each(t, function(i, v) nt[i] = v end) return nt end
       if system_lib.type_of(root) ~= system_lib.TABLE then
What is system_lib?  (Just in case Joe hasn't got it, either.)