Not so long ago, I posted a tutorial about how to program Corona apps more modularly, to make organizing and maintaining your code a much easier task.
Today, I’m going to tackle modular coding from a slightly different approach, and suggest a new technique that might actually help improve performance and squash memory-leak bugs you may be experiencing.
But before I begin, here’s why I’m writing this article in addition to the previous modular coding tutorial that was posted just last month. In a comment to the previously published tutorial, Corona developer Steven K wrote:
modules are awesome especially when you work with several people on one project but I’m always afraid of using it because you have to use global functions and variables when you use modules 🙁
Don Quach (from Spriteloq) also chimed in:
From my experience, all modules create globals even if you try to specify local.
He recommended a third-party function, unrequire (below), which allows you to unload a module that you required-in:
If you’re using external modules in the same way I described in my modular coding tutorial last month, then I highly recommend you make use of the unrequire() function (thanks Don!).
I was able to use the function in many instances (and it proved very useful!), but I ran into the difficulty of deciding when to use it for some modules.
What if you have a module that you’re regularly accessing functions from? After spending some time with it, I realized that the unrequire() function, while useful, tends to add more complexity to a project—more complexity than a Corona app should require (no pun intended). You should just be able to require things in without thinking about when to UN-require them.
My proposed solution? Since the general rule of thumb in Lua is to try your best to avoid using globals altogether, let’s see if we can do that in regards to external modules as well. Let’s restructure our modules so that we never cause them to force globals upon your otherwise pristinely coded app. 🙂
Abolishing the module() Function
Right now, you are likely creating an external module like so:
And here’s how you use the functions within that module:
The problem with examplemodule.lua (above) is that the module() function makes use of the global namespace (as you can see by looking at the unrequire() function). Not only that, the functions you define within the module are also defined as global functions, which is also easy to see (source).
Here’s a way you can rewrite examplemodule.lua (above) and still use it in exactly the same way, without needing functions like unrequire(), and without using globals—all while reducing the potential for memory leaks, errors, and crashes to occur.
I’ve inserted comments throughout the code to help explain it a little better, but the “gist” is that I’ve removed the use of the module() function, was able to localize everything within the module (no use of globals), and module usage remains completely identical, meaning that if you rewrite your modules using the method shown above, the rest of your code should be able to be exactly the same.
The use of Lua’s own module() function may very well be the reason why amazing scripts such as the Director Class (by Ricardo Rauber) and possibly some others end up causing memory usage to gradually climb, even when you’re absolutely sure you’re doing everything else right.
My challenge to you: rewrite all of your external modules in the format I described in my example above, to include your favorite scripts (such as Director). In short, I want you to abolish the use of the module() function, while still reaping the benefits of modular coding!