1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 12:27 PM
So I have a nested table:
{
[test1234] = {
[Version]=1.2.0,
[Name]="Verinian Desktop Environment",
[Type]="Operating System",
},
}
Now I try to do this code:
local tab = fs.open("config/versions.lua", "r")
print(type(tab))
print(tab)
for k, v in pairs(tab) do
print(v)
end
It keeps coming back as:
table
table: 0x024eb150
function: 0x01f50310
function: 0x025040d8
function: 0x024db070
The nested table isn't a function?
89 posts
Location
Munich, Germany
Posted 07 November 2014 - 12:54 PM
Well I think you have to unserialize the table after loading it from the file in order to turn it into a table you can work with ?
Now its only showing the table pointer (or whatever you call it) and maybe lua can not differ this from a function pointer.
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 12:58 PM
Well I think you have to unserialize the table after loading it from the file in order to turn it into a table you can work with ?
Now its only showing the table pointer (or whatever you call it) and maybe lua can not differ this from a function pointer.
It worked in older versions using unserialize, now unserializing it will add loads of new lines and syntax that is out of place!
It as been done before!!
Does anyone know how to format that table to work?
3057 posts
Location
United States of America
Posted 07 November 2014 - 01:09 PM
The problem here is: you are iterating through the file handle. Including file.readAll() (a function), file.readLine() (a function), and file.close() (a function)
Now, if you were iterating through file.readAll(), you'd simply get an error because it's a string.
797 posts
Posted 07 November 2014 - 01:17 PM
You need to read the file first, then unserialize it. You can do that like this:
local h = fs.open( file, "r" )
local content
if h then
content = h.readAll( )
h.close( )
else
error( "could not read file", 0 )
end
local tab = textutils.unserialize( content )
if type( tab ) ~= "table" then
error( "(the file format is messed up)", 0 )
end
Another problem is that the keys in the table are referring to variables, not strings. To have a string index in a table, use either of the following
{
key = "value";
["key"] = "value";
[key] = "value"; -- this will look for the variable called key and use it's value, rather than the string "key"
}
Edit:
Well I think you have to unserialize the table after loading it from the file in order to turn it into a table you can work with ?
Now its only showing the table pointer (or whatever you call it) and maybe lua can not differ this from a function pointer.
It worked in older versions using unserialize, now unserializing it will add loads of new lines and syntax that is out of place!
It as been done before!!
Does anyone know how to format that table to work?
That's incorrect. Unserialize effectively loads "return " followed by the string you are trying to unserialize, and returns that. Therefore, you can unserialize any Lua value, not just tables. It's serialize that adds the extra lines, as it's trying to make it more human readable.
Edited on 07 November 2014 - 12:21 PM
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 03:18 PM
You need to read the file first, then unserialize it. You can do that like this:
local h = fs.open( file, "r" )
local content
if h then
content = h.readAll( )
h.close( )
else
error( "could not read file", 0 )
end
local tab = textutils.unserialize( content )
if type( tab ) ~= "table" then
error( "(the file format is messed up)", 0 )
end
Another problem is that the keys in the table are referring to variables, not strings. To have a string index in a table, use either of the following
{
key = "value";
["key"] = "value";
[key] = "value"; -- this will look for the variable called key and use it's value, rather than the string "key"
}
Edit:
Well I think you have to unserialize the table after loading it from the file in order to turn it into a table you can work with ?
Now its only showing the table pointer (or whatever you call it) and maybe lua can not differ this from a function pointer.
It worked in older versions using unserialize, now unserializing it will add loads of new lines and syntax that is out of place!
It as been done before!!
Does anyone know how to format that table to work?
That's incorrect. Unserialize effectively loads "return " followed by the string you are trying to unserialize, and returns that. Therefore, you can unserialize any Lua value, not just tables. It's serialize that adds the extra lines, as it's trying to make it more human readable.
When I unserialize it thats what it does?
797 posts
Posted 07 November 2014 - 03:30 PM
Unserializing will turn it from a string into a Lua value. If that string reads something like "{ }", it will turn it into a table.
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 03:39 PM
Unserializing will turn it from a string into a Lua value. If that string reads something like "{ }", it will turn it into a table.
I did what you said:
local tab = fs.open("config/versions.lua", "r")
print(type(tab))
print(tab.readAll())
tab = textutils.unserialize(tab.readAll())
print(type(tab))
for k, v in pairs(tab) do
print(v)
end
print(tab["test1234"].Version)
the print(type(tab)) before for loop comes back with nil…
797 posts
Posted 07 November 2014 - 04:14 PM
Can I see the contents of the versions.lua file?
Edit: if it is the same as what you posted in the OP, it will error. Remember what I said about [key] using the value of the variable called key (just like you can do t
to get number indexes). There is a problem with this though, if you have a key which is nil, like below, it will error.
local key = nil
local t = { [key] = 5 } -- error here, cannot have nil indexes
The same goes for if you haven't defined a variable. So, in the versions.lua file, if you haven't changed it, it will be doing "[test1234]={}" and as there is no variable called test1234 it will error. Textutils will catch this error though, and rather than returning the error message, just return nil
Edit 2: maybe this will make more sense
Edited on 07 November 2014 - 03:20 PM
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 04:22 PM
Can I see the contents of the versions.lua file?
Edit: if it is the same as what you posted in the OP, it will error. Remember what I said about [key] using the value of the variable called key (just like you can do t
to get number indexes). There is a problem with this though, if you have a key which is nil, like below, it will error.
local key = nil
local t = { [key] = 5 } -- error here, cannot have nil indexes
The same goes for if you haven't defined a variable. So, in the versions.lua file, if you haven't changed it, it will be doing "[test1234]={}" and as there is no variable called test1234 it will error. Textutils will catch this error though, and rather than returning the error message, just return nil
Edit 2: maybe this will make more sense
{
["test1234"] = {
["Version"] = 1.2,
["Name"] = "Verinian Desktop Environment",
["Type"] = "Operating System",
},
["dsgdkflg"] = {
["kjdsskjfg"] = "kjngjfdg",
["jdkkjnv"] = "idfsgnfdl",
},
}
797 posts
Posted 07 November 2014 - 04:25 PM
Weird, what does print( tab.readAll() ) print out? Is it the correct contents of the versions.lua file?
Try this code:
Spoiler
local h = fs.open( "config/versions.lua", "r" )
if not h then
print "Failed to open file"
end
local content = h.readAll( )
h.close( )
print( content )
local tab = textutils.unserialize( content )
print( type( tab ) )
I doubt it but there might be a problem with calling h.readAll() twice, which would explain why you're getting the error. Storing it in a variable like above would fix that.
Edited on 07 November 2014 - 03:28 PM
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 04:41 PM
This is what I get:
[attachment=1961:Capture.PNG]
I don't know why :S
1140 posts
Location
Kaunas, Lithuania
Posted 07 November 2014 - 04:42 PM
I doubt it but there might be a problem with calling h.readAll() twice, which would explain why you're getting the error. Storing it in a variable like above would fix that.
It is actually a problem. The file contents in ComputerCraft can only be read once per file handle. That means, when you call fileHandle.readAll() the only thing you can do next with fileHandle is to call fileHandle.close().
1847 posts
Location
/home/dannysmc95
Posted 07 November 2014 - 04:43 PM
It works when the table is local to the file… So if I store that table and at the start just put a variable and "=" and it works then, but not when loaded….
1080 posts
Location
In the Matrix
Posted 07 November 2014 - 10:13 PM
Let me expand on what mklegoman is saying.
local tab = fs.open("config/versions.lua", "r")
print(type(tab))
print(tab.readAll()) --# This reads the file
tab = textutils.unserialize(tab.readAll()) --# Oh no, the file's already been read we can't read anymore. this is nil
print(type(tab))
for k, v in pairs(tab) do
print(v)
end
print(tab["test1234"].Version)
I would change it to something like this.
local tab = fs.open("config/versions.lua", "r")
print(type(tab))
tbl = textutils.unserialize(tab.readAll())
tab.close() --#This will close the file. since you can't read anymore anyways
print(type(tbl))
for k, v in pairs(tbl) do
print(v)
end
print(tbl["test1234"].Version)