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

Variables not changing?

Started by BPowell3, 30 March 2017 - 07:15 PM
BPowell3 #1
Posted 30 March 2017 - 09:15 PM
Hey guys, I'm really confused….

I have a program like this (this is only part) loaded as an API:


showWarn = true
silent = false
local function except()
print(silent) --for debugging purposes
if silent == false then
  --print error details
end
return(true)
end
local function warn(mode)
print(showWarn) --for debugging purposes
if silent == false and showWarn == true then
  --print warning
end
return(true)
end


In the lua prompt, if I load the API, set "silent" or "showWarn" to their opposite values, and then run those functions, the functions print the variables as being their original value…. Like… What?

Even more strange, if I print the value from the prompt using:

print(testapi.showWarn)
It shows as the value I set it to…. Then run the function… Suddenly its the original value again… How does that figure? I've checked numorous times and even used find in notepad++ to check, and the only times those variables are read or set is mentioned above…. So I really don't understand what's happening…. Help? Thanks in advance
Bomb Bloke #2
Posted 31 March 2017 - 12:55 AM
Every function that runs uses an environment table to store any globals you define. Usually this is simply the same table used by the function which called them - which can be traced all the way back to _G.

When loading an API in ComputerCraft, the file containing the API's code is loaded up as a function, and given a new unique environment table before execution (one which also gives access to _G, via some metatable magic). When the code's completed, that table then contains keys for each global variable the script defined. These are then all copied out into a new table (without the metatable linkage), which gets plonked into _G as the final "loaded API".

https://github.com/alekso56/ComputercraftLua/blob/master/bios.lua#L575

So when you do:

print(testapi.showWarn)

… you are referring to the copy of "showWarn" which was placed into the API table that ended up in _G.

And when you do:

testapi.warn()

… that function will be referring to the original "showWarn" variable within the special environment table os.loadAPI() created.

The solution is "don't try to access variables within APIs directly". If you want to change or retrieve their data values, add functions to the API which do that for you, and then call them.