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

[SOLVED] Program doesn't work on first try, but second

Started by BrunoZockt, 01 March 2017 - 09:07 PM
BrunoZockt #1
Posted 01 March 2017 - 10:07 PM
Hey Guys,

as said in my last Post, I got 2 problems, 1 mentioned in this thread, the other here: http://www.computerc...le-doesnt-work/
This problem is already described in the title. Everytime I start my program on a turtle that booted rigth before, it errors out (KIBeta:870: attempt to call nil).
But when I end it and start the program again (without rebooting the turtle) it works perfectly fine.


menu[menustate].draw()
Line 870

The variables in this line are of course completly defined as you can see here:

menustate = "Home"

menu = {
  ["Home"] = {
	options = {"Start", "Options", "Quit"},
	draw = drawMain
  },
  ["Start"] = {
	options = {"Go!", "Options", "Home", "SHelp"},
	draw = drawStart
  },
  ["Options"] = {
	options = {"Start", "Home", "Help"},
	draw = drawOptions
  },
}


I got the theory that the turtle somehow safes the code (and the variables with it, which is bad) even when the program is closed.
What leads me to this theory is that everytime I change the code (in my external text editor) I have to reboot the turtle to make the code work. I remember that I simply had to restart the program when I programmed half a year ago.
I really hope somebody can help me with this, I'm despairing.

Full code: http://pastebin.com/fptxKN9n

Thanks in advance,

Bruno
Edited on 02 March 2017 - 08:01 PM
supernicejohn #2
Posted 01 March 2017 - 11:04 PM
(Contemplating on wether or not to answer this one too, but hey first to the mill is the first to grind your corn, and I tend to be early, and "I really hope somebody can help me with this, I'm despairing." makes me think you'd like a quick reply.)
When I read the title I wondered if the problem included global variables, and looking at the code, it does:

draw = drawMain
might seem all well and good, but the fact is that 'drawMain' is in fact nil when that assignment is made.
As to why it works the second time, and why I figured it'd involve global variables is because further down the code, drawMain is defined, and when run a second time the program will actually assign 'draw' as the global variable 'drawMain' left by the last run of the program.
It'll do that because 'drawMain' will be defined, because doing "varName = nil" isn't wrong in itself, rather calling a non-existent function is wrong, and gives precisely the aforementioned error.

One trick to fix this would be to add "local myFunction, mySecondFunction" to the start of the program, and then it will know to call (what ever is assigned to for example 'myFunction') at the time of running the parent function, since it will know where to "look" for a function.
Also using local variables is a good habit, for one it eliminates these problems, and it doesn't clutter _G as global variables do. :)/>

What leads me to this theory is that everytime I change the code (in my external text editor) I have to reboot the turtle to make the code work. I remember that I simply had to restart the program when I programmed half a year ago.
That's odd, but it might be related to the global variable problem. Try running the program twice after editing it :P/>
BrunoZockt #3
Posted 02 March 2017 - 03:55 PM
(Contemplating on wether or not to answer this one too, but hey first to the mill is the first to grind your corn, and I tend to be early, and "I really hope somebody can help me with this, I'm despairing." makes me think you'd like a quick reply.)
When I read the title I wondered if the problem included global variables, and looking at the code, it does:

draw = drawMain
might seem all well and good, but the fact is that 'drawMain' is in fact nil when that assignment is made.
As to why it works the second time, and why I figured it'd involve global variables is because further down the code, drawMain is defined, and when run a second time the program will actually assign 'draw' as the global variable 'drawMain' left by the last run of the program.
It'll do that because 'drawMain' will be defined, because doing "varName = nil" isn't wrong in itself, rather calling a non-existent function is wrong, and gives precisely the aforementioned error.

One trick to fix this would be to add "local myFunction, mySecondFunction" to the start of the program, and then it will know to call (what ever is assigned to for example 'myFunction') at the time of running the parent function, since it will know where to "look" for a function.
Also using local variables is a good habit, for one it eliminates these problems, and it doesn't clutter _G as global variables do. :)/>

What leads me to this theory is that everytime I change the code (in my external text editor) I have to reboot the turtle to make the code work. I remember that I simply had to restart the program when I programmed half a year ago.
That's odd, but it might be related to the global variable problem. Try running the program twice after editing it :P/>

Thanks for your awnser.

With your help I tried out two things:
  1. Moving my drawMain() function (and all the other draw functions) to the top
  2. Setting all variables to local
The first thing solved my problem after a lot of sorting around.
But setting every variable to local, which I tried although it doesn't change anything (I thought :lol:/> ) because then I can be sure that it doesn't interfere with other programs, resulted in a total mess.
Switching through my menu options works but the GUI doesn't, so I can't see which option is currently selected. Many pages of my GUI are just completly broken, because everything is where it doesn't belong.
Maybe I just didn't understand how the local statement works, but I thought this shouldn't change anything.

I would really appreciate any help!

Thanks in advance,
Bruno
Lupus590 #4
Posted 02 March 2017 - 06:13 PM
have you looked at this? http://lua-users.org/wiki/ScopeTutorial
BrunoZockt #5
Posted 02 March 2017 - 07:03 PM

Thanks for the suggestion, but I already knew everything that was explained there. So I still can't figure out my mistake.
Edited on 02 March 2017 - 06:04 PM
Lupus590 #6
Posted 02 March 2017 - 08:09 PM
You could try predefining the things which break


--# won't work as otherLoop isn't defined yet
local function badLoop()
  otherLoop()
end
local function otherLoop()
  badLoop()
end

--# predefining otherLoop fixes the issue
local badLoop --# not even assigning anything, just say it exists or will exist
local function badLoop()
  otherLoop()
end
function otherLoop() --# we already said that it's local, bad things happen if we say it again - this could also be your problem with local
  badLoop()
end
Edited on 02 March 2017 - 07:10 PM
BrunoZockt #7
Posted 02 March 2017 - 09:00 PM
You could try predefining the things which break


--# won't work as otherLoop isn't defined yet
local function badLoop()
  otherLoop()
end
local function otherLoop()
  badLoop()
end

--# predefining otherLoop fixes the issue
local badLoop --# not even assigning anything, just say it exists or will exist
local function badLoop()
  otherLoop()
end
function otherLoop() --# we already said that it's local, bad things happen if we say it again - this could also be your problem with local
  badLoop()
end

Thank you for your help. I already thought something like this could be the solution but I was too lazy to go through the variables 1 by 1 and hoped for an easy solution :P/> .
But I guess I have to :wacko:/> :D/>

Bruno