globals-featGlobal variables and functions are risky and there are a few crucial things you should know about them before you consider it safe to add one to the _G table, Lua’s “global table.”

Let’s quickly discuss the _G table. In Lua, variables that are all uppercase and prefixed by an underscore are considered private variables for Lua’s use, for example, _VERSION. You should not attempt to use these in your program under any circumstances. Well, notice that _G is uppercase and prefixed by an underscore as well! This means that it’s a reserved structure for system use.

But it’s so convenient!

It’s true: global variables and functions are convenient. By using the _G table, you can create a variable that’s accessible from both main.lua and any module, for example a Storyboard scene. But here’s the dirty little secret…

…are exactly the same. In other words, Lua puts every global variable into the _G table, and everything you explicitly put in _G is available by its variable name:

So why do some people tell you to put things in the _G table? Well, one reason is to clearly identify that you’re declaring a global variable, as opposed to a variable that you meant to be local but simply forgot to prefix with local.

No harm = No foul?

Some people have reported in the Corona Forums that they can print variables to the console, but Corona’s error and warning messages have stopped functioning. The likely cause of this was that the user created a global variable named debug — i.e. _G.debug. This effectively “trashed” access to an internal library that Corona uses to output debug messages.

If you print out the _G table on an empty main.lua using the following method…

…you can see all of the things already present there:

All of the APIs listed in the API Reference under the (globals) entry are here, as well as some undocumented items like debug and several core API groups like math, string, and audio. With this in mind, you might assume that you can write code like this:

However, what you’ve done is “trash” these Corona libraries, so you won’t be able to play audio or use the type() function — and that timer isn’t going to time anything!

“So I won’t use those global names…”

Not so fast! These are the libraries that you shouldn’t overwrite today, based on a completely blank main.lua file. The list above assumes that you haven’t require’d any additional libraries or modules, whether they be Corona libraries like physics, your own modules, or third-party libraries like director. In addition, other things may slip into the global space that you’re simply not aware of. Finally, as we roll out new features and libraries, we might use a global term that you’re currently using, in which case upgrading to a new version of Corona SDK would suddenly conflict with your app.

Simply put: Don’t use globals!

“Wait,” you may plead, “I still need to access something that I haven’t declared yet, or access variables between modules.” Fortunately, both of these are easy to accomplish without using globals.

The first case — accessing something you haven’t declared yet — is solved by the forward declaration method. As a Lua/Corona programmer, understanding scope is essential. If you need to use a variable (usually a function) before you declare it, simply set a variable and use the alternate function declaration syntax:

At the end, we just assign the function that does the work to the variable doSomething. In this way, the makeSomethingHappen function becomes aware of the doSomething function since it was declared “above” the code chunk which requests it.

And to solve the second case — accessing variables between modules — you can simply create a Lua file named mydata.lua (or similar) with the following contents:

Then, in each of your Lua modules, simply require the module as follows:

Now you can use the myData table just like you would _G and circumvent the risk of overwriting things in the _G table, as well as avoid the general issues and pitfalls that come along with globals.

In summary

We’ve been stressing the “avoid globals” stance for a long time now, and as you can see, there is essentially no further need for global variables or functions. With careful scoping and management of the internal _G table, you can accomplish everything you need without them.

Questions or comments? Please contribute to the discussion below.

Excerpt from:  

Tutorial: Goodbye Globals!