This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
IndustrialLemon's profile picture

Serialize not placing in order

Started by IndustrialLemon, 08 November 2018 - 05:33 AM
IndustrialLemon #1
Posted 08 November 2018 - 06:33 AM
Hello, took a small break but I'm back with more ideas and more walls to scale. Right now I'm trying to understand why when I utilize textutils.serialise() it results in the table I serialized to be jumbled. I haven't done a whole lot of research so if this is quite obvious I'm sorry. Reason being I'm going to bed soon and I'd just like to get my question in for tomorrow.

over here I have my code for receiver (turtle),

rednet.open("left")
local id, message = rednet.receive("remote")
print(textutils.serialise(message))

and over here I've got the pocket computer I'm sending from and it's code,

local coords = {
    x = 1,
    y = 5,
    z = 2,
    }
rednet.open("back")
rednet.send(9, coords, "remote")

These are test scripts in order to better understand how to deal with sending these variables over rednet so that they can be used as args for a shell.run("goto", …) function.
The bigger picture reason for this endeavor is to create a function that receives the coords of the player(he/she's pocket computer) and runs goto for the turtle to return to the player.

Anyone's help is of course always appreciated. Thanks guys!
Bomb Bloke #2
Posted 08 November 2018 - 07:03 AM
Lua's tables are a cross between arrays and hashmaps.

To treat them as an array, you simply index into them numerically - ideally starting at index 1, and working your way up through the elements contiguously. Pretty much all the functions in the "table" library expect to be used on a table constructed in this manner.

However, they can also be treated as a hashmap - simply by using any other sort of object as a key with which to index into them. For example, coords.x indexes into the "coords" table using the string "x". Lua handles this by hashing "x", and using the numeric result to pinpoint where in memory the corresponding value should be read from or written to.

The thing with hashmap keys is that they don't really have an order worth using. They're not stored alphabetically, nor in order of assignment, or anything like that - they're simply stored by hash. So when textutils.serialise() is asked to create a string out of table keys, there's no easy way to predict the order in which it'll find them.

The function could be rigged to find all keys, sort them alphabetically, and then use the results to build the final string. This isn't done because there simply isn't any point - unserialising the results later will rebuild an "identical" copy of the original table either way.
IndustrialLemon #3
Posted 08 November 2018 - 03:28 PM
Huh, odd. So you are saying that I'd be able to reference it pre-serialization by doing coords[1], coords[2]… I tried that and it only produced nil. But I'll also try the coords.x, coords.y pre and post serialization.

UPDATE : coords.x appears to be working for me! Still confused why I can't seem to reference the table by integer PRE serialization. If I understand you correctly, the serialization is what changes this regular table into a hashmap.
Edited on 08 November 2018 - 02:32 PM
Bomb Bloke #4
Posted 08 November 2018 - 11:59 PM
Still confused why I can't seem to reference the table by integer PRE serialization.

If you don't put values in using numeric indexes, then you can't take values out using numeric indexes.

If I understand you correctly, the serialization is what changes this regular table into a hashmap.

No. You started out treating your table as a hashmap from the get-go, by using strings (x/y/z) for your keys. A table isn't an array xor a hashmap, it's both, and can be treated as either at any time.

Eg, see if you can figure out how this'll act before you run it:

Spoiler
local myTable = {
	"oranges", --# Values without specific indexes/keys
	"pears",   --# are automatically assigned numeric
	"apples",  --# indexes and go into the array.
	"mangos",
	
	x = 4,	 --# Key values are hashed and go into the map.
	y = 3,
	z = 2,
	
	[10] = "bananas"  --# You can target specific numeric indexes, too.
}

for i = 1, #myTable do  --# For each contiguous numeric index in myTable do...
	print(i .. ": " .. myTable[i])
end

print()

table.sort(myTable)  --# Only acts on the contiguous numeric indexes.

for i = 1, #myTable do
	print(i .. ": " .. myTable[i])
end

print()

for key, value in pairs(myTable) do  --# For EVERY element in myTable do...
	print(key .. ": " .. value)
end
Edited on 08 November 2018 - 11:00 PM
IndustrialLemon #5
Posted 09 November 2018 - 01:15 AM
Ah gotcha. Thank you for the in-depth explanation and example.