I am using metatables. you can use metatables to specify how a table should behave in certain situations.
here is a great tutorial on metatables.
I will now make my usual feeble attempt at actually explaining my code (explanations really aren't my strong suit as I end up thinking faster than I type/talk and confusing people…. sorry in advance :P/>/>)
once you have read the tutorial above you will understand that the second table in the setmetatable command's parameters contains information about how the tRecords table should behave. the 3 situations I am preparing it for are: if you try to index (v: access) a part of the table that has no value (__index), if you try to make a new index (n: value/entry) in the table that was previously nil (__newindex) and if you call the table as a function (__call)
both the newindex and call metatables just call the save function which is pretty easy to understand, it checks if you specified a value to set, if you did then it sets it (there will always be a value in the __newindex case of course) and once that is done it then saves the table to a file (using the filename at the top of the script)
the index metatable is the important part as this opens the specified file and retrieves the saved info there so you can use it in your code
just so you also know the rawset and rawget commands can be used to add/retrieve info from a table and ignore the existing metatable when you do. this is VERY important. here is an example where it is needed. you have a metatable that changes what happens when you add a value to a table, this metatable calls a function that saves that index on a DIFFERENT table as a backup or copy/whatever and then also saves it to the normal table. if you do not use rawset to save the value to the normal table then you are defining a new index right there and that will call the metatable all over again and continue doing so in a loop that will freeze and eventually crash your program….
–———————————————————–———————————————————————————————That being said there are 3 major problems with this code. firstly I do not know of any metatable that allows you to change what happens when you change an EXISTING value so if you make a new index
tRecord[1]='test01'
it will save that to the file, then when you change that existing value
tRecord[1]='test02'
it will change the value in the table but it will not save that value to file, this is why I allowed you to call the table as a function in stead… there is a way that I could make it work but it would make the code a little messy. I will post it with this method at the bottom of this post
second problem: the metatable only looks in the file if there isn't an existing value in tRecord then it will not look in the file as it only looks when you try to index a nil value (once again I do not know of a metatable for any indexing). this can actually be incredibly useful as you can use rawset to add a value to the table that will then ignore what is in the file FOR THAT SESSION ONLY
third problem: you must recall something from the table before adding a value or the file will be overwritten with the empty table. this is my fault and is a stupid mistake, it will be corrected in the code to follow
–———————————————————–———————————————————————————————
function addRecord(filename)
local function recall(t,index)
if fs.exists(filename) then
local oFile=io.open(filename,'r')
local temp=textutils.unserialize(oFile:read())
oFile:close()
return index and temp[index] or temp
end
return not index and {} or nil
end
local function save(t,index,val)
local temp=recall()
if val then
temp[index]=val
end
local oFile=io.open(filename,'w')
oFile:write(textutils.serialize(temp))
oFile:close()
end
return setmetatable({},{__index=recall;__newindex=save;__call=save})
end
I think this code is as good as it will get…. in this case we now have a function (addRecord) and you use it like so
myTable=addRecord('stored')
and myTable becomes a table that will store and recall information from the file 'stored'. it will no longer get confused when modifying an existing value, there is no problem with loading it before changing a value and this way you can use tables of a name you choose… enjoy
EDIT: forgot to mention… fully tested and functional. you can even have multiple tables pulling from the same file