Tutorial: Goodbye Globals!

Share on Facebook0Share on Google+4Tweet about this on TwitterShare on LinkedIn1

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.

Share on Facebook0Share on Google+4Tweet about this on TwitterShare on LinkedIn1
Rob Miracle

Rob Miracle creates mobile apps for his own enjoyment and the amusement of others. He serves the Corona Community in the forums, on the blog, and at local events.

This entry has 52 replies

  1. Joe says:

    I like the myData.lua bit – good tutorial, thx

  2. Excellent tutorial. It makes perfect sense now. And there really IS no excuse not to use a separate lua file to hold all my goodies.

    Thanks a lot!


  3. Kerem says:

    Great tutorial as usual. Its so easy to rely on Globals in head down quick and dirty programming mode but it gets ugly real quick as your project grows. I will implement the myData.lua right away. Thanks much!!!

  4. Kerem says:

    Follow-on question… Which is better

    To put the following as globals in your main.lua

    require “sqlite3”
    require “storyboard”
    require( “widget” )

    or the following in each module including main.lua

    local sqlite3 = require “sqlite3”
    local storyboard = require “storyboard”
    local widget = require( “widget” )

    Any performance tradeoffs in declaring the modules and requiring locally?


  5. Rob Miracle says:

    You should always do the “local” thing. There is zero benefit from doing it the other way that I’m aware of.

  6. Kerem says:

    Great! Local it is then! Thanks for your guidance.

  7. Mo says:

    THANK YOU ROB! One of the best Corona tutorial ever!


  8. Mo says:

    Just to make sure: how would you set variables under myData?
    Something like

    local M

    musicFlag = true
    test = 10

    Return M

    And use it in another module as:

    Print (M.test)



    • Andreas says:

      Hi Mo,

      you would use:

      –my global space
      local M = {}

      M.musicFlag = true
      M.test = 10

      return M


  9. Dave Baxter says:

    I always use this method for storing my variables I need across the app –



  10. Mo says:

    Thanks Andreas. Your way makes more sense! Great info Dave!


  11. Lerg says:

    Good point. But having one global “MyData = {}” in your main.lua is totally legit. Saves you time on writing “local MyData = require(‘mydata’)” each time. Or you can require this module as global again in main.lua if you want to store some variables in a separate file.

  12. Rob Miracle says:

    @DaveBaxter, I have used that concept for most of my apps as well. Keep in mind that a future update might use storyboard.state in a different way. That variable may not be protected in the future. In fact I was adding an attribute of my own to storyboard and an update nailed me. I forget which one, maybe .debug. This way, you are not touching any existing API space. And for those that want a quick Search and Replace:

    local _myG = require(“mydata”). Just like _G that you’re used to, just puts the letters “my” in front.

    @Lerg, yes, it saves you having to type that line several times, but in that case myData will be inserted into _G since it’s global and has the potential to overwrite someone else whose using the same technique (if you use any 3rd party solutions). Besides, data that exists in global space is referenced differently than local space and global space is much more resource costly to reference. This is why we tell you to localize things like the math library. Basically globals are looked up in a hash, where frequently locals are either in registers or found by index (a quicker operation).

    We can’t stop you from using globals that way, but …

  13. Pablo Isidro says:

    Thank you!! Really clear!

  14. Lerg says:

    @Rob yeah, 3rd party code is often not pretty. If it’s something small I just refactor and clean it on my own. So far had no need to use some really big 3rd party modules. The largest would be twitter+oauth and key encryption/decryption modules.

    As for speed advantage it’s not really matters as long as you don’t access it several hundreds or thousands times on an event. If you do access it a lot you would better have it cached in the current function anyway for the best results (local MyVar at the top of a module is not enough), so again not a big difference of use or performance.

    Lua only has a partial performance impact itself. The biggest impact is on the renderer. It’s more important to optimize graphics rather than cache some variables. Not to tell how entire algorithms often may be optimized to gain significant boost.

    Also I do store all my libs and corona libs (storyboard, audio, widget) as globals. For me the clean code is more important than those few milliseconds you can save on some events.

    Well, yeah, the only thing I want to point out is that using globals is not evil as long as you know what are you doing. For novices the general advice would be to avoid _G of course.

  15. J. A. Whye says:

    Bah, humbug!

    I think a completely valid thing would be for Corona Labs to prefix their use of globals (kind of a namespace-type thing) so the chances of me or anyone else bumping into them is pretty much nil.

    Because I think for “audio = true” in main.lua to screw up the actual SDK means Corona Labs did something wrong, not whoever wrote that line of code.

    How about you guys use _G.CoronaLabsAPI = {} and throw everything in there? Then there’s only one thing we have to stay away from and future features won’t break our code, etc.

    I understand there are performance reasons to avoid globals, but breaking the SDK as a reasons seems kind of wobbly.


  16. Rob Miracle says:

    Jay, name spacing would be great, but using your example you would have to make every api call like:


    Prefixing every API call with the name space would get tiring on programmers in a hurry.

    • J. A. Whye says:

      Okay, but that was just off the top of my head. You guys are all smart, someone come up with a better solution than mine — one that’s not, “Don’t use globals.” 😉


    • Chris Woodhams says:

      I have to agree with Jay here. This is a pretty hypocritical post. You’re saying “Don’t use globals because Corona is already using globals.” It would be very easy to put everything inside a package Object like `CL.display.newImageRect()` and if a programmer finds this “tiring”, they can simply write `local display = CL.display` at the top of the file, just like doing an import in many other languages.

      • Rob Miracle says:

        I don’t feel it’s hypocritical. Lua allows it. The things that are global, are for the most part Lua’s functionality. A good portion of the SDK requires you to require a module. When you’re building a development tool, you have to balance the need to require everything vs having core functionality available with out having to require it.

        If you’re an experienced developer and you know what you’re doing and globals make sense, use them. But for many new and developing programmers, globals are a trap to be avoided.

      • J. A. Whye says:

        And just to resurrect this blog post again… 😉

        Since I wrote the initial “Hey, I wanna use globals!” message I’ve changed my tune. While I’ll still use a global or two here and there when it makes sense (usually smaller projects), for the most part I stick with local variables. Where I used to use globals, I now typically make a “myvars.lua” file as discussed toward the end of the blog post.

  17. Paolo says:

    Nice tutorial, I find useful the idea of looking into _G for potential compatibility problems. Just for sharing my practice, I use very few globals in non performance critical bits such as music and app state (which view and tab is the user on and so on) and I name those variable in such a way that any accidental override would be unlikely (e.g. bgMusicAGlobal or currentViewGlobal). For the rest I decide which module owns a variable (it is usually the module that creates the variable) and use that module M table for storing. The idea of pooling some variables in one module is interesting because it saves the pain of remembering which module own which variable.

  18. Dave says:

    My favourite part is “..oSomething. In this way, the makeSomethingHappen function becomes aware of the doSomething function since it was decla..”

    Made me happy =]


  19. Good tutorial, thank you. I promise I will clean up my lazy, bad habits!

  20. JonPM says:

    Is there a significant performance difference by using the mydata.lua method vs globals? Or is that simply to avoid “trashing” the predefined libraries?

  21. Rob Miracle says:

    Globals are the slowest to access variables in Lua. Members of a local table are faster. The word: “significant” is important here. If you’re setting up a one page utility app with a couple of buttons and fetching some data from a web service that updates once an hour? Then it’s insignificant. You’re moving a thousand bullets around the screen? It’s probably significant.

    Performance is only one factor. Not trashing your own code is just as important as not trashing the predefined libraries. I can’t tell you the number of storyboard examples where they create:

    background = display.newImageRect(“background.png”, 570, 360)

    in one scene, they to another and execute the same line of code and you got yourself a memory leak. Or they go back to the previous seen without purging and wonder why the background image didn’t change.

    Or people who use other people’s libraries and each other’s globals stomp on each other.

    If you know what you’re doing, and you name space them accordingly and you are not in a situation where performance counts, then use them… You know what you’re doing. But I would ask, why would you want to use them? Since you need to namespace them to avoid conflicts, that means typing some prefix on the variable name, why not make that namespace “mydata.” Want to type even less? How about myG. That’s just one character more than _G.

  22. mike kelly says:

    I could almost cry: this is so beautiful… thanks, Rob (appropriately named) Miracle…

  23. Leo says:

    Hi there,

    I’m new to Lua and working on my project. Disclaimer: I’m using the physics game with the falling box as a starting point and adapting that code.

    So I tried implementing a “player.lua” file to contrain general information regarding my player character (image locations, stats, etc). I wanted to make it accesible across my different “levels”, so this seemed like the way to go. However, I’m having a weird error regarding passing a string of my picture name. My code is as follws:


    local playerData = {}

    playerData.playerImageLoc = “\”crate.png\””

    return playerData


    local storyboard = require( “storyboard” )
    local scene = storyboard.newScene()

    — include Corona’s “physics” library
    local physics = require “physics”
    physics.start(); physics.pause()

    local playerData = require(“player”)
    local player


    — forward declarations and other locals
    local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth*0.5


    — NOTE: Code outside of listener functions (below) will only be executed once,
    — unless storyboard.removeScene() is called.


    — Called when the scene’s view does not exist:
    function scene:createScene( event )
    local group = self.view

    — make a player (off-screen), position it, and rotate slightly
    –player = display.newImageRect( playerData.playerImageLoc, 90, 90 )
    player = display.newImageRect( “player.png”, 90, 90 )
    player.x = display.contentWidth/2
    player.y = (display.contentHeight)/4

    — add physics to the player
    physics.addBody(player,”static”, { density=1.0, friction=0.3, bounce=0.3 } )

    group:insert( player )

    The error says Corona can’t find the image, despite it existing. If I hard code that string, no error is thrown. Thanks for any advice you can offer.

    • Rob Miracle says:

      Is there a reason you are putting quotes into the string. The file name doesn’t actually have quote marks in it does it? Try:

      playerData.playerImageLoc = “crate.png”

  24. Yo.
    Thanks for the tutorial.

    I am a C, C++, C# programmer.
    Going thru the documentation and learning the differences between those and Lua.
    Good times so far.

    However I am having one issue.
    In C++/C# I am used to creating a class, and then an object from that class, and then using the . to reveal all of the available public members in intellisense.
    Something like this:
    public class Stuff
    public int x = 1;
    public int y = 1;

    public Stuff obj = new Stuff();
    obj. ————> from here intellisense will show [obj.x, obj.y] and I will select one.

    But in Sublime/Corona/Lua:
    local s = {}
    s.x = 1
    s.y = 1
    return s

    local Stuff = require(“Stuff.lua”)
    Stuff. —————> there will be no suggestions from intellisense after the dot.

    However if I use one of the members:
    Stuff. ——————> now intellisense will show [Stuff.x], but it will not show [Stuff.y], until after it is also used.

    Is there a way to see all of the members of a table in intellisense before using them?
    Or is that just part of how Lua works?
    This is something that I can become accustomed to, but it feels strange as I have to remember the members of a file, or look them up, the first time I use them.

    Anyways, thanks.
    Corona is really cool, and I’m enjoying the docs.

  25. Nick says:

    Doesn’t work..!!
    All I get is “Attempt to index local..”
    “mydata.lua” is located in the same place as main.lua?
    I’ve written the simplest code..and it’s not reading the other file..please elaborate..?

    • Rob Miracle says:

      Can you post this question in the forums? We are going to want to see some code and it doesn’t render well here in the comments.

  26. Dont tell the people to not use globals. There are things that just are global and would cause a lot of pain and errors by having to carry them through every function they are needed in.

    Why should your language setting or your click sound handle should not be global?

    Emulating globals by requiring a ‘myData.lua’ just adds unconvenience and more code that isn’t neccessary.

    So ‘Never use globals’ is as dumb as ‘Always use globals’, just use them with care and know the consequences.

  27. Rob Miracle says:

    Hi Johannes, we may have to agree to disagree. This is like a goto statement. Its there, you can use it and there are some circumstances where it might make sense, but in 99 % of the circumstances, its worth the extra effort for code readability, sustainability and supportability if you do not. Globals fall into this case. You have no control over what happens in global space. You might right over something that’s already a global (set a variable called “debug” and watch your print statements stop working…). A 3rd party library might stomp on your usage. There are too many ways that globals can harm your program than the gains you get from using them.

    The only safe way to use globals is to namespace your variables so that other things don’t trump you. Some people might believe that using _G is that name space, but that’s not the case. _G.fred and fred are the exact same variable. If you want to name space your variable, you have to put some tag in the variable name, like perhaps:


    I doubt someone is going to use that name (though myglobal probably is less safe than gonzo_score….)

    By the time you name space your variables, you have in effect typed in enough extra work, that accessing it from a table is the same thing:


    The only trick is to require the table in each module and there are performance benefits from accessing the data in locally required table vs. global space.

    Sure, a seasoned programmer who knows what they are doing can make effective use of globals, just like that “goto” statement, but generally speaking, it’s bad form, hard to support in the long term, poor performing and simply dangerous in creating hard to find and fix bugs.


    • Hey Rob,

      Sure, you’re right with the namespace pollution argument and the performance of locals. A collegue of mine once wondered why everything was broken because he used a global variable named ‘object’ 🙂

      But you can name things like _focus or FOCUS. Often the things that just are global are also things that are needed often, so it’s tedious to always have to write myglobal.var, so myglobal will eventually turn into glob.var, or g.var and that’s the point where we could just have used a properly named global variable. (and personally I dislike the dots everywhere)

      Lua’s strength is building small things fast, because it doesn’t force oop and it’s bloatedness or any other strict structure onto us. We don’t build big software that’s hard to maintain with big developer teams.
      And often, certainly not always, less code (with less structure) is easier to understand and to maintain.

      Not long ago I would also never even think about introducing a global variable. I had to actually lern a little bit of ‘sloppyness’, now my life is better. Some programmers have to learn strictness, some have to learn sloppyness. Globals are there for a reason and I think sometimes they are the adequate tool.

      so agreed 🙂

  28. Edwin says:

    Do I need to manually clean up the myData table in myData.lua or does the system automatically clean it at some point?


    • Rob Miracle says:

      There is no automatic cleanup of myData. What you put in the table, you are responsible to clean up. That said consider this:

      1. Most of the data you are going to put into that table is pretty small if you’re not referencing display objects or audio. The numbers, strings and booleans and other small tables you might add, isn’t a huge hit on memory.

      2. If you do put in display objects and you are using a scene manager like Composer (or it’s older brother Storyboard) and those objects are also in the scene’s view display group, then they will be cleaned up as well.


  29. Pixin says:

    Thanks Rob. One question, in your Tutorial: Cleaning Up Display Objects and Listeners, posted on April 2, 2013, you state “Local references in functions are nil’ed out when the function ends.”

    Would you verify, is it better to declare a local variable inside a function rather than add the data to a variable table (that would later need to be manually cleaned up)? By better that also includes faster processing and cleanup. Seems like that would be yes. Is that right?

    • Rob Miracle says:

      I guess I should qualify that. When you call a function and you have a local variable inside the function, that variable isn’t kept around after the function ends unless it’s being referenced as an up-value in another function inside that function. The next time you call that function all of your local variables will be new. In other words it won’t remember what they held last.

      If you allocate memory, like creating a new image and you don’t return a reference to that image, when you leave that function, that object is lost. Hopefully with Automatic Reference Counting that Xcode uses, it will be released, but to be safe (and I don’t know how Java handles that memory on Android), you could possibly still cause leaks.


  30. Ale says:

    Hi, 2 question:

    1- is there a benchmark about the speed of local instead global variables?

    2- in corona i like simplicity: if i need every time to write down “local user = require ‘src.model.user” for every scene i write more stuff. More code means also more errors possibilities and less elegance.. for now i’m using something like that:

    _G.M = {
    user = require ‘src.model.user’,
    level = require ‘src.model.level’

    M is for model

    And in various scene i use M.user to access to it.

    Is this a good solution?


  31. Rob Miracle says:

    I can’t put my hands on bench marks right away, but there is an older blog post that had some optimizations and I think globals were covered in that.

    Obviously Lua supports globals, so they are there to be used, but unless your app is uber simple or you are extremely careful then they are more problems than they are worth. Because it’s the fast path for new programmers to allow code and variables to work in multiple modules, it leads to problems because new programmers will invariably reuse a global and then they can’t figure out their problems.

    Let me tell you a story from my early programming days. I came up with my own sorting method called the “Robbie Sort”. it was based on the bubble sort method. Bubble sort was the easiest to write but it was the worst performing sort ever… until the Robbie Sort came along. At the the same time it was the most efficient sort method ever too. I wrote it in a few less lines than the bubble sort by saving programmer time since it was less code. And on a 10 member array, it really didn’t matter, but if the array had any substantial data in it, the performance sucked badly because it was even slower than the bubble sort.

    The point is you can save programmer time or you can save CPU time. Being a good programmer is finding the balance between the two and know when to be “efficient” (less code) or be “efficient” (faster code).

    Now for your example, you’re already creating a table in the global table:
    Lua already only loads the modules once. It’s just a matter of you having to require it in each module to get a local reference to it vs. having a global reference to it.

    Consider typing this over and over:


    That’s 5 extra characters per reference you have to type.

    local user = require(“src.model.user”)

    is 38 characters. If you reference your user variables and functions 8 times or more you’re going to save code by using the local reference and I think would be far less error prone.

    But as I said, if it’s working for you and Lua permits them, then you can use them, though we personally feel, it’s not worth it.


  32. Skava says:

    This is getting annoying.

    I got my main.lua and mydata.lua

    In mydata.lua I have:
    local M = {
    M.Playerscore = 0
    Return M;

    Then in my main.lua i have:
    local data = require (“mydata”)

    print(“playerscore: ” .. mydata.Playerscore); — in main function

    But when I run the simulator I get this error: “module ‘mydata’ not found:resource(mydata.lu) does not exist in archive.” The file is in the same place as the main.lua file. I’ve pretty much copied and pasted the code from here so I don’t think there is a typo anywhere

    • Rob Miracle says:

      The “Return M” is case sensitive. Try: return M

      Also, you do local data = require(“mydata”) but later reference mydata.Playerscore. You can fix this by either:

      local mydata = require(“mydata”)


      print(“playerscore: ” .. data.Playerscore);

      • Skava says:

        the “Require M” was a typo on my part of the comment, basically I didn’t do that in the code, it was always “return M”

        Also what you suggested didn’t work either. I didn’t work either; I had it as:

        local data = require(“mydata”)
        print(“playerscore: ” .. data.Playerscore)

        • Rob Miracle says:

          Blog comments are not a good way to support code. Please take this to the forums (http://forums.coronalabs.com) and ask your question there. Please cut and paste your actual code and put it inside of [lua] and [/lua] tags. If we can’t see your real actual code, typos through us off.


  33. Kenny says:

    Hey Rob. Amazing article as usual!

    I’m still a newbie to Corona SDK. From your article, I understand the importance of avoiding globals and using more locals. The main concern I have with using more local variables is if I exceed more than 200 within a certain scene, I get an error “Attempt to index nil with upvalues more than 200” or something of that nature. Is the best solution to this is to create local tables and assign everything in there?

    Do you have any tutorial that helps to explain what we can do if we keep encountering this error message?

    • Rob Miracle says:

      If you follow the tutorial, you will have a table that you’re storing variables in. Table’s are not subject to the 200 variable limit. In my first app before I understood all of this I hit the 200 limit frequently. So I just created a couple of different tables and moved my local variables into the table.

  34. AbdelGhafour says:

    When I use a separate file like myData, and I require something inside it like: local widget = “widget”
    Would widget be considered local when I require “mydata” in another file?

    • Rob Miracle says:

      The first time your app requires a module, it loads the module and makes it available for other modules to use. So if you load widget in main.lua for instance: local widget = require(“widget”) the module is loaded and main.lua has a local reference to it. Now you go to mydata.lua and do a local widget = require(“widget”) there, the existing module is already in memory and mydata.lua will now have a localized reference to it.