←  Ask a Pro

ComputerCraft | Programmable Computers for Minecraft

»

Table index is nil when using dofile

Dahknee's Photo Dahknee 17 Jul 2016

Okay hello there!

I have made a test program, which I wrapper in one big function and this all works perfectly. when I execute the wrapping function, so I string.dump 'd it, and attempted to dofile() it, but my error is table index is nil? I have never seen that error before so I am not sure exactly what I am doing wrong...?

I just got the dumped file name (example: "dump.lua") and then did the following:

executeTest = dofile("dump.lua");


But i get: bios:14 table index is nil

I am not trying to execute the function either, this is just the dofile function... Anyone have any ideas?

Thanks in advance.

NOTE:
This is purely just based off of interest, I don't plan on doing anything stupid with it, just interested on what's possible.
Quote

Bomb Bloke's Photo Bomb Bloke 17 Jul 2016

Basically it's telling you that this isn't valid Lua:

local myTable = {[nil] = "Hello World"}

Hard to comment further as you haven't bothered to show the code, but a shot in the dark guess is that it involves the environment.

View PostDannySMc, on 17 July 2016 - 10:41 PM, said:

I am not trying to execute the function either

Er, yes you are? dofile ~= loadfile
Quote

Dahknee's Photo Dahknee 18 Jul 2016

View PostBomb Bloke, on 17 July 2016 - 11:37 PM, said:

Basically it's telling you that this isn't valid Lua:
local myTable = {[nil] = "Hello World"}
Hard to comment further as you haven't bothered to show the code, but a shot in the dark guess is that it involves the environment.

View PostDannySMc, on 17 July 2016 - 10:41 PM, said:

I am not trying to execute the function either
Er, yes you are? dofile ~= loadfile

I didn't "bother" because it's about 12,000 lines of bytecode which would lag up my tablet. If possible I am actually using an unreleased program as a testing point, would you mind if I PM'd you the data? just because I don't wish to publicly release it just yet?

Again, I didn't actually know that executes it, although that would make a lot of sense as loadstring was coming back as nil. I wonder if there is a limit to CC's string.dump? maybe it didn't do it all? or missed some...
Quote

Bomb Bloke's Photo Bomb Bloke 18 Jul 2016

View PostDannySMc, on 18 July 2016 - 12:41 AM, said:

I didn't "bother" because it's about 12,000 lines of bytecode which would lag up my tablet. If possible I am actually using an unreleased program as a testing point, would you mind if I PM'd you the data?

Sure, so long as you include what it was built out of. The bytecode itself isn't so useful for debugging purposes.
Quote

MKlegoman357's Photo MKlegoman357 18 Jul 2016

First of all, when saving the bytecode you have to save it using a "wb" mode, because it contains bytes that will be corrupted if using "w" mode. Second, dofile, loadfile and any other function will not work because they open the file in "r" mode, not "rb" mode which is required to properly load the bytecode.
Quote

Bomb Bloke's Photo Bomb Bloke 18 Jul 2016

Huh. So we can't load bytecode at all? I lose track. :(
Quote

Dahknee's Photo Dahknee 18 Jul 2016

View PostMKlegoman357, on 18 July 2016 - 08:07 AM, said:

First of all, when saving the bytecode you have to save it using a "wb" mode, because it contains bytes that will be corrupted if using "w" mode. Second, dofile, loadfile and any other function will not work because they open the file in "r" mode, not "rb" mode which is required to properly load the bytecode.

I did wonder whether I needed to use rb / wb, because it works in C when loading other bytecode using Lua...

So can we load it ato all?
Quote

The Crazy Phoenix's Photo The Crazy Phoenix 18 Jul 2016

View PostBomb Bloke, on 18 July 2016 - 08:26 AM, said:

Huh. So we can't load bytecode at all? I lose track. :(
Read with rb mode, concatenate, and use loadstring. I've done it before, it works.
Quote

Dahknee's Photo Dahknee 18 Jul 2016

View PostThe Crazy Phoenix, on 18 July 2016 - 09:09 AM, said:

View PostBomb Bloke, on 18 July 2016 - 08:26 AM, said:

Huh. So we can't load bytecode at all? I lose track. :(
Read with rb mode, concatenate, and use loadstring. I've done it before, it works.

Concatenate what?

local bc = fs.open("dump.lua", "rb");
data = bc.readAll();
bc.close();

local newfunc = loadstring(data);

Do you mean the above or other? apologies if I am wrong, not sure I understand completely what you are saying.
Quote

The Crazy Phoenix's Photo The Crazy Phoenix 18 Jul 2016

When you read with rb, it's faster to store each char in a table and then uses table.concat. readAll is not a valid method in rb mode (according to the wiki).
local h = fs.open(file, "rb")
local t = {}
for b in h.read do  -- Read all bytes
	t[#t + 1] = string.char(b)
end
local dump = table.concat(t)  -- Concatenate the strings
local func, err = loadstring(dump)  -- Load the string

Edited by The Crazy Phoenix, 18 July 2016 - 03:08 PM.
Quote

Dahknee's Photo Dahknee 18 Jul 2016

View PostThe Crazy Phoenix, on 18 July 2016 - 03:08 PM, said:

When you read with rb, it's faster to store each char in a table and then uses table.concat. readAll is not a valid method in rb mode (according to the wiki).
local h = fs.open(file, "rb")
local t = {}
for b in h.read do -- Read all bytes
t[#t + 1] = string.char(B)/>
end
local dump = table.concat(t) -- Concatenate the strings
local func, err = loadstring(dump) -- Load the string

Interesting, will have a go when I am back, thanks.
Quote

Bomb Bloke's Photo Bomb Bloke 19 Jul 2016

View PostThe Crazy Phoenix, on 18 July 2016 - 03:08 PM, said:

When you read with rb, it's faster to store each char in a table and then uses table.concat.

Surely it'd be faster to unpack to string.char()?:

local h, func, err = fs.open(file, "rb"), {}

for b in h.read do func[#func + 1] = b end

h.close()

func, err = loadstring( string.char( unpack( func ) ) )
Quote

Emma's Photo Emma 19 Jul 2016

View PostBomb Bloke, on 19 July 2016 - 02:32 AM, said:

--snip--

Quite so,
in fact, after running a bunch of benchmarks here are the average computation cycles over 10 seconds:
Bomb's character unpack: 128831.2
Table concatenation: 19178

Using string.char(unpack(func)) is about 6.5 times faster.
Edited by Incinirate, 19 July 2016 - 02:54 AM.
Quote

Bomb Bloke's Photo Bomb Bloke 19 Jul 2016

... for a certain string length. I'd expect the gap to widen as it gets longer.

There's a bit of a catch in that some versions of Lua (as used by some ComputerCraft emulators) don't like unpacking large amounts of values. Doesn't seem to be an issue in CC proper, though.
Quote