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

Dynamic index function (test:11: attempt to index (a nil value))

Started by flaghacker, 28 July 2014 - 04:26 PM
flaghacker #1
Posted 28 July 2014 - 06:26 PM
I have made this function to return a part of a table at the address specified by the second argument:

local function getIndex(t, i)
  local fi = i[1]
  local ni = {}
  for key, value in pairs(i) do
	ni[key - 1] = value
  end
  print(#ni .. ": " .. fi)
  if #ni == 0 then
	return t[fi]
  end
  return getIndex(t[fi], ni)
end

local a = {b = {c = {"lol"}}}
local b = {"a", "b", "c", 1}

local result = getIndex(a, b )
print(result)
It errors with "test:11: attempt to index (a nil value)". I know this error means the table "t" doesn't exists, but I can't figure out why.

EDIT: The error doesn't occurs the first time the function runs. The debug print at line 7 prints out the following:

3: a
2: b
Edited on 29 July 2014 - 09:21 AM
MKlegoman357 #2
Posted 28 July 2014 - 07:00 PM
The problem is your first ('a') table's structure. The first and only key in that table is 'b' but you are assuming it is 'a'. Also, currently you are not checking if there is actually an existing key in the last line ( return getIndex(t[fi], ni) ), that's why you are getting that error.

EDIT: also, forward declair your function so you could use it inside itself:


local getIndex
function getIndex ()
  ...
end
Edited on 28 July 2014 - 05:27 PM
flaghacker #3
Posted 29 July 2014 - 07:42 AM
Thanks, it works! Are you sure I need to forward declare it? It works without…

And with this code I can't get an "ArrayIndexOutOfBoundsException", right?
theoriginalbit #4
Posted 29 July 2014 - 07:49 AM
it works without because it is adding it into the global scope. you should always keep anything that doesn't need to be in the global scope out of it, so yes, a forward declaration would mean it is localised as well as be invoked internally. As for the stack overflow, no, this will not happen, due to the fact that you're using the return, this removes the current function call from the stack before adding the new one (there's a proper name for this, but I've had a mental blank currently).
Edited on 29 July 2014 - 05:49 AM
flaghacker #5
Posted 29 July 2014 - 09:47 AM
Isn't the function local now? It has "local" in front… Is that somehow cancelled by the recursion?

The term is "proper tail calls".
theoriginalbit #6
Posted 29 July 2014 - 09:55 AM
well yes it is local now, but you're getting the attempt to call nil error (reason why you get the error, read the spoiler inside the 'What is a function pointer?' spoiler).
What I was meaning is with MKlegoman357's solution, if you were to remove the forward declaration it would make it a global variable.


The term is "proper tail calls".
that's it, tail call.
Edited by
flaghacker #7
Posted 29 July 2014 - 10:41 AM
I am not getting a "attempt to call nill" error. This is my current code:

local function getIndex(t, i)
  local fi = i[1]
  local ni = {}
  for key, value in pairs(i) do
		ni[key - 1] = value
  end
  print(#ni .. ": " .. fi)
  if #ni == 0 then
		return t[fi]
  end
  return getIndex(t[fi], ni)
end
local a = {b = {c = {"lol"}}}
local b = {"b", "c", 1}
local result = getIndex(a, b )
print(result)

Also, in my first post, on line 17:

local result = getIndex(a, b )
What is that " B )/>'? I tried editing that away, but it keeps returning.
Derp, it's also in my second code.

Edit: Fixed in all posts.
Edited on 29 July 2014 - 09:20 AM
theoriginalbit #8
Posted 29 July 2014 - 11:01 AM
I am not getting a "attempt to call nill" error.
so you're not, I could have sworn I read `attempt to call nil`, not `attempt to index nil`… sorry for the confusion there.

What is that " B )/>'? I tried editing that away, but it keeps returning.
that's the forum software trying to create B)/> but the code tags don't allow it, to remedy this just place a space between the b and the )
flaghacker #9
Posted 29 July 2014 - 11:17 AM
What is that " B )/>'? I tried editing that away, but it keeps returning.
that's the forum software trying to create B)/> but the code tags don't allow it, to remedy this just place a space between the b and the )
Thanks, edited all my posts.

Thanks everybody for helping me.