Jump to content




Cannot serialize type function


  • You cannot reply to this topic
8 replies to this topic

#1 Megaddd

  • Members
  • 4 posts

Posted 12 October 2013 - 06:24 AM

Hello, I've just recently finished my first 'major' project with OpenPeripheral, it was working fine and dandy for about a week until it decided that 'num' had suddenly become a function.

Problematic Function:
Spoiler

Full code:
Spoiler

The program is meant to compare a list of ME system items with a user-input list of items, assign names to matched items, print their quantities, calculate deltaQuantities and give an ETA based on delta and current quantity.
Issues arise when the program tries to serialize the current user-input list of tracked items (trackedItemsdat).

Logically the only items that should ever end up on the list are coming from tonumber(arg2) and tostring(arg3). Furthermore what baffles me is that it adds and saves the first tracked item fine, and were you to terminate it there, restart, and add another item - everything works as intended, but add a second and suddenly serialize finds a function somewhere in trackedItemsdat.

I'm really confused as to why this is happening, especially because it was working fine running for 5 days straight chunkloaded, until I came back from afk to this error:
parallel: 22: textutils: 166: Cannot serialize type function.
The code was not modified prior to that.
I then loaded a better Serialize program I found here as 'slize' to see if the server changed/updated the textutils in rom, but only to get the same error. So it seems somehow a function is indeed making it's way into trackedItemsdat and I can't track it down. I've even tried to iterate-print the whole list and it didn't seem to print any functions.

Please help me in my struggles, as it is my first bigger CC project I made from scratch, if anyone with a fresh perspective on the code could locate the problem, I would be deeply grateful.

Thanks for taking time to read this in advance :)

#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 12 October 2013 - 01:24 PM

Split into new topic.

Try creating a modified version of the serialize function that will tell you where it's at in the table when it finds the function value.

#3 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 12 October 2013 - 02:42 PM

If I really wanted to prevent functions from getting into trackedItems, I'd use some metatable magic... I know it's kind of advanced... But whatever.
local trackedItems = setmetatable({}, {
    __newindex = function(tbl, key, value)
        if type(value) == "function" then error(string.format("here it is! (%s)", key), 2) end
        rawset(tbl, key, value)
    end
})
local trackedItemsdat = {}

-- ...


#4 Megaddd

  • Members
  • 4 posts

Posted 12 October 2013 - 02:47 PM

View PostLBPHacker, on 12 October 2013 - 02:42 PM, said:

If I really wanted to prevent functions from getting into trackedItems, I'd use some metatable magic... I know it's kind of advanced... But whatever.
local trackedItems = setmetatable({}, {
	__newindex = function(tbl, key, value)
		if type(value) == "function" then error(string.format("here it is! (%s)", key), 2) end
		rawset(tbl, key, value)
	end
})
local trackedItemsdat = {}

-- ...

This looks promising, but the thing with trackedItems is that it's a table with tables in it, inside which, I fear, the functions hide.

#5 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 12 October 2013 - 02:50 PM

View PostMegaddd, on 12 October 2013 - 02:47 PM, said:

-snip-
Try this then:
local function functionDetector(tbl, key, value)
    if type(value) == "function" then error(string.format("here it is! (%s)", key), 2) end
    rawset(tbl, key, type(value) == "table" and setmetatable(value, {__newindex = functionDetector}) or value)
end

local trackedItems = setmetatable({}, {__newindex = functionDetector})
local trackedItemsdat = {}

-- ...


#6 Megaddd

  • Members
  • 4 posts

Posted 12 October 2013 - 03:38 PM

Your code ran fine in an isolated environment, however after I patched it into my code it started telling me that trackedItemsdat and trackedItems are both nil at table.insert.

ins = {["id"] = out,["name"] = str}
if trackedItems == nil then trackedItems = {[1]={["name"]="Oakwood",["id"]=17}} end
if trackedItemsdat == nil then trackedItemdat = {[1]={["name"]="Oakwood",["id"]=17}} end
table.insert(trackedItems,ins)
table.insert(trackedItemsdat,ins)

I assume it's safe to say there's a server-side issue regarding ComputerCraft?
I mean, my program runs fine for 5 days, all of a sudden functions end up where they're impossible to end up, and now this nil-proofed code still says that it has a 'bad argument: table expected, got nil'
Either that, or I need to re-write absolutely everything to clean it up, as checking for errors right now is extremely difficult. :(

edit:
section of function with patched function-hunterâ„¢
Spoiler


#7 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 12 October 2013 - 07:00 PM

Quote

if trackedItemsdat == nil then trackedItemsdat = {[1]={["name"]="Oakwood",["id"]=17}} end


#8 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 13 October 2013 - 01:50 AM

In case you don't see the underlined character, he's pointing out that you missed an "s".

#9 Megaddd

  • Members
  • 4 posts

Posted 19 October 2013 - 05:46 AM

My original code is very messy, guess I'll dedicate a weekend to rewrite the entire script with more loops and compact code, as a lot of what I've done could've been done with less code. It's also very messy, using similar variables like trackedItemsdat and TrackedItems, which could've been mixed up in some parts of the code easily, I'll post the finished work once I'm done to the programs section and link it here eventually. Thanks for the help with list management! Appreciated :).





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users