Jump to content




Trouble placement of array variables and functions


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

#1 aceyo369

  • Members
  • 18 posts

Posted 17 August 2014 - 04:18 PM

Although i encounter a common error here which is line 21, attempt to index ? (a nil value) but there is something that make this error even more complicated, which is the different placement of array and functions that correspond to each other. I need help to give my tips on how to arrange my codes so that i won't get the error.

The error occurs when i want to call a function that seems to be nil...

This is the code:(UNDERLINED IS WHERE ERROR OCCURS)

local select = 1
local running = true

local function clear()
term.clear()
term.setCursorPos(1,1)
end

local function printMenu(menustate)
clear()
for i = 1, #menustate do
if i == select then
print(">"..menustate[i].opt)
else
print(menustate[i].opt)
end
end
end

local function control()
changeState("control")
end

local function keyHandler(menustate)
event, key = os.pullEvent()
if key == 200 and select > 1 then
select = select - 1
elseif key == 208 and select < #menustate then
select = select + 1
elseif key == 28 then
menustate[i].action()
end

end

local menu = {
["main"] = {
[1] = {opt = "Control", action = control},
[2] = {opt = "Command", action = command},
[3] = {opt = "Exit", action = exit}
},
["control"] = {
[1] = {opt = "Lights", action = light},
[2] = {opt = "Door", action = door}
},
["command"] = {},
["lights"] = {}
}

local menustate = menu["main"]

local function changeState(newstate)
menustate = menu[newstate]
end

while true do
printMenu(menustate)
keyHandler(menustate)
end

Edited by aceyo369, 17 August 2014 - 05:05 PM.


#2 RickiHN

  • Members
  • 15 posts

Posted 17 August 2014 - 05:22 PM

What exactly is this function "changeState" and where is it defined? And why are you feeding it the string "("control")"

#3 aceyo369

  • Members
  • 18 posts

Posted 17 August 2014 - 05:33 PM

local menu = {
["main"] = {
[1] = {opt = "Control", action = control},
[2] = {opt = "Command", action = command},
[3] = {opt = "Exit", action = exit}
},
["control"] = {
[1] = {opt = "Lights", action = light},
[2] = {opt = "Door", action = door}
},
["command"] = {},
["lights"] = {}
}

local function changeState(newstate)
menustate = menu[newstate]
end

changeState("control") simply change the menustate to a control menu

#4 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 17 August 2014 - 06:26 PM

Try defining your functions before calling them.

#5 aceyo369

  • Members
  • 18 posts

Posted 17 August 2014 - 06:45 PM

So if i define the function before calling for them, there will be another error called as it is calling for menu["control"] but the variable is later then defined. So to make everyone clear, i have an issue for the defining of variables and functions that corresponds with each other, one comes after another still gives error...

These four parts causes the problem, i need better ways to arrange them...

local menu = {
["main"] = {
[1] = {opt = "Control", action = control},
[2] = {opt = "Command", action = command},
[3] = {opt = "Exit", action = exit}
},
["control"] = {
[1] = {opt = "Lights", action = light},
[2] = {opt = "Door", action = door}
},
["command"] = {},
["lights"] = {}
}

local function changeState(newstate)
menustate = menu[newstate]
end

local function control()
changeState("control")
end

local function keyHandler(menustate)
event, key = os.pullEvent()
if key == 200 and select > 1 then
select = select - 1
elseif key == 208 and select < #menustate then
select = select + 1
elseif key == 28 then
menustate[select].action()
end

Edited by aceyo369, 17 August 2014 - 06:47 PM.


#6 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 17 August 2014 - 06:51 PM

Fixed it for you:
local menu = {
	["main"] = {
		[1] = {opt = "Control", action = control},
		[2] = {opt = "Command", action = command},
		[3] = {opt = "Exit", action = exit}
	},
	["control"] = {
		[1] = {opt = "Lights", action = light},
		[2] = {opt = "Door", action = door}
	},
	["command"] = {},
	["lights"] = {},
}

local function changeState(newstate)
	menustate = menu[newstate]
end

local function control()
	changeState("control") 
end

local function keyHandler(menustate)
	event, key = os.pullEvent()
	if key == 200 and select > 1 then
		select = select - 1
	elseif key == 208 and select < #menustate then
		select = select + 1
	elseif key == 28 then
		menustate[select].action()
	end
end
The issue: you were missing an end. It was easy to see after properly indenting your code. Also I believe there was a comma missing.

#7 aceyo369

  • Members
  • 18 posts

Posted 17 August 2014 - 06:58 PM

It is still not fixed, now the error occurs at the menustate[select].action(), attempt to call nil

#8 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 17 August 2014 - 09:06 PM

In Lua, you have to first define any variables (functions are variables too) before you can use them, but if you really need to use a variable before you can define it (and don't worry, there are a lot of cases where this kind of thing is needed) you can forward-define the variable like so:

local foo --// Define the variable, it's going to be nil for now

local function bar ()
  print(foo + 2) --// We use the variable "foo" assuming it is a number, even though it's still nil
end

foo = 3 --// We define the variable later

bar() -->> 5

Note that you do not have to do this if you are using global variables, but using them is a bad habit and you should always, when possible, use local variables.

#9 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 17 August 2014 - 10:20 PM

View Postaceyo369, on 17 August 2014 - 06:58 PM, said:

It is still not fixed, now the error occurs at the menustate[select].action(), attempt to call nil
Uhm... Please post the full code. Some of the actions are *not* defined here, which might be the problem.

Edit: I'm not sure if this is related to your question or not, but this may help you... I wrote a quick little "menu" code that is pretty simple to use. Simply give the function a few strings, and the user will be able to choose between them.

Spoiler

Edited by KingofGamesYami, 18 August 2014 - 12:49 AM.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users