[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua Pickle error?
- From: Joe Andresen <joe.andresen@...>
- Date: Sat, 23 Jan 2010 20:30:04 -0800
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
-- Edited by: Joe Andresen, Jan 2010
-- Freeware
----------------------------------------------
function pickle(t, filename)
return Pickle:clone():pickle_(t,filename)
end
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" )
else
filename = filename .. ".lua"
io.output(filename..".lua")
end
if type(root) ~= "table" then
error("can only pickle tables, not ".. type(root).."s")
return false
end
self._tableToRef = {}
self._refToTable = {}
local savecount = 0
self:ref_(root)
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))
end
s = s.."},\n"
end
string.format("{%s}", s)
io.write("return ",s)
io.close()
return true
end
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")
end
end
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
end
return ref
end
----------------------------------------------
-- unpickle
----------------------------------------------
function unpickle(filename)
--if type(s) ~= "string" then
-- error("can't unpickle a "..type(s)..", only strings")
--end
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
end
end
return tables[1]
end
function test()
local t = {
name = "foo",
ssn=123456789,
contact = { phone = "555-1\r\n212", email = "
foo@foo.com"},
}
t.t = { 1 }
t.contact.loop = 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 == ut.contact.loop)
print("subitem test:"); eq(ut.contact.phone == t.contact.phone)
print("number value:"); eq(ut.ssn == t.ssn)
print("number index:"); eq(ut[10] == 11)
print("table index: "); eq(ut[ut] == 5)
end
function eq(b)
if b then print(" succeeded") else print(" failed") end
end
end
test()
On Sat, Jan 23, 2010 at 11:23 AM, Andre Leiradella
<aleirade@sct.microlink.com.br> 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.)