Anyone who has used Lua for a while learns that global variables are not our friends. Since any mention of a variable that hasn’t been set is assumed to be a reference to a global whose value is nil
, that means the silliest typo (e.g. varl
vs. var1
) can wreak havoc in the most finely-tuned code. As such, best practice is to avoid the use of global variables in Lua code entirely.
There’s a module which has been around for a long time called strict.lua
— available here and many other places — which will check for the use of globals and throw an error if it finds any. Some developers don’t like it because throwing errors means it’s hard to run on a large body of existing code, but if you’re starting a new project it can save a lot of time.
For this reason, we’ve now built a similar capability directly into the Corona Simulator. With the following API call, you can now get warnings about the use of globals so you can eliminate them permanently:
Runtime:setCheckGlobals( true )
Doing so will give you warnings like this:
Apr 15 12:27:22.155 WARNING: reading global nil 'onTapLogo' stack traceback: /Users/gimli/corona/metagame/main.lua:91: in function 'setupTapHandler' /Users/gimli/corona/metagame/main.lua:96: in main chunk
Pass false
to the same function to turn the feature off. Since it only issues warnings, it’s easier to use in existing code than strict.lua
.
System globals
Alongside this feature comes a new “safety net” built into the Corona Simulator which prevents the inadvertent overwriting of system globals and the attendant chaos that would ensue. Some of you will be familiar with the issues an innocent line of code like this can cause:
debug = true
This has the effect of disabling all errors in your project because it overwrites the system library debug
with a boolean value. Hours can be wasted if you’re unlucky enough to do this, because nothing makes sense anymore.
Fortunately, Corona SDK now prevents overwriting of system globals (e.g. debug
, display
, print
, etc.) and issues an error message like this:
Apr 15 12:27:21.875 ERROR: cannot overwrite system library 'debug' stack traceback: /Users/gimli/corona/metagame/main.lua:9: in main chunk
Of course, you can still override things like print()
if you really want to, but you have to think about it a little more carefully and make your override local to your project code:
local debugMode = true local cachePrint = print local function print(...) -- Note local definition if debugMode then cachePrint(unpack(arg)) end end
Note that this doesn’t affect customizing system libraries with new APIs or member variables since that doesn’t involve overwriting the system global with another value, but rather it just amends its existing attributes.
Most people don’t need to worry about it, but if you’re deep in the heart of Lua and are accessing the _G
globals table, you can still do so via Runtime._G
, but this is advanced usage and the safety net comes off. And, if you really, truly need to change the value of a system global, you can always use Lua’s rawset()
(but if you really need to do it, you’d know this already).
Conclusion
The features outlined in this article are available in Daily Build 2016.2866 and later. Happy hunting for globals!