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

Weird program error on reboot

Started by mannybjh, 25 May 2019 - 02:56 AM
mannybjh #1
Posted 25 May 2019 - 04:56 AM
I am currently trying to write a turtle dispatching system for my single player world (Minecraft 1.6.4), and I am experiencing a weird bug. The program works, but whenever I restart the computer using shutdown or reboot command, it doesn't work as designed.


local ACTIONS=
{
["exit"] = endProgram,
["addturtle"] = addTurtle,
["removeturtle"] = removeTurtle,
["listturtles"] = listTurtles
}
function endProgram()
shell.exit()
end
function addTurtle()
print("Turtle ID: ")
term.setCursorPos(12,4)
id = read()

local h = fs.open("TurtleIDList", fs.exists("TurtleIDList") and "a" or "w")
h.writeLine(id)
h.close()
end
function removeTurtle()
if(not fs.exists("TurtleIDList")) then
  print("No Turtle ID's Saved")
  sleep(3)
  return
end
print("Turtle ID: ")
term.setCursorPos(12,4)
id = read()
local currentTurtles = fs.open("TurtleIDList", "r")
local ids = {}
while true do
  currentId = currentTurtles.readLine()
  if(currentId == nil) then
   print("End Of IDS")
   break
  end
  if(currentId == id) then
   print("ID Removed")
   sleep(3)
  else
   ids[#ids + 1] = currentId
  end
end
currentTurtles.close()

local newTurtles = fs.open("TurtleIDList", "w")
for i, writeID in ipairs(ids) do
  newTurtles.writeLine(writeID)
end
newTurtles.close()
end
function listTurtles()
if(not fs.exists("TurtleIDList")) then
  print("No Turtle ID's Saved")
  sleep(3)
  return
end

local currentTurtles = fs.open("TurtleIDList", "r")
local ids = {}
while true do
  currentId = currentTurtles.readLine()
  if(currentId == nil) then
   break
  end
  ids[#ids + 1] = currentId
end
currentTurtles.close()

for i, writeID in ipairs(ids) do
  print(writeID)
  sleep(1)
end
sleep(3)
end
while true do
term.clear()
term.setCursorPos(1,1)
print("SkyNet Dispatch")
term.setCursorPos(1,3)
print("Action: ")
term.setCursorPos(8,3)
local action = string.lower(read())
action = action:gsub("%s+", "")
local func = ACTIONS[action]
if(func) then
  func()
else
  print("Action '"..action.."' Not Found")
  sleep(3)
end
end

What happens after the computer turns on, is no matter what I type in for an action, it automatically says Actions not found even if it is a valid action. If I Ctrl+T out of the program and run it from terminal again, it works as designed. Until the user restarts the computer, of course. Thanks for your help in advance.
Bomb Bloke #2
Posted 25 May 2019 - 08:07 AM
Remember that scripts execute from top to bottom. When you initially run your script on boot, the first thing it tries to do is build your ACTIONS table: but none of the variables you're trying to copy into it contain anything yet, so you "fill" the table with a bunch of nils.

Your script then proceeds to define all of your functions into the global scope, where they remain even when your script terminates. This is why re-running your script then allows you to assign some actual data into the ACTIONS table - the global scope only clears when you reboot your computer.

Note that in later versions of ComputerCraft, the global scope is cleared when a script ends. Generally you should be localising everything you can.

Edit:

It may also help to know that Lua always assigns by value, never by reference. Confusingly, when you attempt to assign a function/table/coroutine you end up assigning a pointer value leading to the relevant area in memory, but working with that pointer value in the variable is not the same as being able to use a variable as a reference.
Edited on 25 May 2019 - 06:28 AM
mannybjh #3
Posted 27 May 2019 - 03:06 AM
Thanks!