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!

    • Jonathan Beebe says:

      @Neils: Thanks for the links! I didn’t know that module() has been deprecated (great to know though, thanks again!). Looks like this tutorial came with good timing :-)

  1. Nice one :) will try it in my project. I wish this was part of the Lua language, if you replace local with private/public keywords, any public functions automatically goes in the M table, the private functions does not. Just a thought. Thx

  2. I actually use Ricardo’s loader class to do all of my module loading – everything then get’s wrapped up into a single object – however I shall look at changing the loader class and my functions that it loads into this new “module-less” format.

    Very informative post thanks Jon (and Niels for the extra info).

  3. Can anybody confirm if there is a difference between

    local testfunction = function(arg)
    ….
    end

    and

    local function testfunction(arg)
    ….
    end

    And what the difference is – which is more efficient?

    Cheers

  4. Hi Jonathan,

    I tried to implement this in my own app but ran into a limitation of this approach, at least for the way I modularized.

    I require all my external modules in main.lua like so:
    local examplemod = require “examplemodule”

    The issue is that some functions of particular modules depend on functions from other modules. Using your method those functions are now invisible/undefined to other modules unless I remove ‘local’ from the require statement. I presume that puts me back to where I don’t want to be, with every function global.

    Is there a way where I can include external modules with dependencies on other external modules and still keep everything global?

  5. Jonathan Beebe says:

    @XenonBL: Since the modules you are requiring in are completely local using this method, why not just require the modules in every module you need them? That is, unless you have some variables you need to access globally across the board (in which case you might just store those directly in the _G table if you cannot find a way around those… For functions though, I recommend just localizing the modules in every module you need them–that way you don’t have to make everything global in your main.lua.

    @Jon: Regarding function syntax, I have read *somewhere* that defining functions (local func1 = function()) yields better performance (but cannot call itself), but I can’t find where I read that. So for the most part, it’s just a matter of personal preference (unless some proper testing can be done, or some links to someone who has can be found).

  6. Good writeup, Jonathan. I think this is a good way to keep things simple and modular – it is the method that I have used in my just-released Corona Library – http://developer.anscamobile.com/code/dmc-corona-library. I opted against the use of module() because I read read the same info in the links that @Niels provided (its use seemed more harmful than useful).

    @XenonBL: If you think some examples would help, I have created several in my library which use this method. In short, they will show what Jonathan suggested – require other modules in those which need them. If interested, they are in the library’s code base, located on github. Check out the link above for more information.

  7. @jonathan Yeah, that works, although at this point my code is separated into dozens of external modules/libraries, which would require a pretty extensive rewrite to get everything working using this new system. Plus, I’m also using third party modules such as Particle Candy, Text Candy, CrawlspaceLib etc. which all still rely on module().

    And what about Ansca’s own ui.lua? (I’m still using it and it’s found in many of the Ansca supplied sample projects ). Plus all the user submitted modules…

  8. I’ve used something like this and it seems to work fine. A couple of differences in the way I use it though…

    I go straight for:

    M.testFunction2 = function()
    print( “Test 2″ )
    end

    return M

    (or in my case function M.testFunction2() )

    i.e. don’t create a local function and then a global reference to it. Is there a difference? Aren’t you ‘globalising’ the function anyway by creating the reference? Does the two step version buy you anything?

    Other thing I do is have truly local functions inside the module which can only be called from within the module (like private methods) i.e.

    in Man.lua:

    local Man = {}

    — local private method
    local function getEyeColour(args)
    if(args.hairColour == “blonde”) then
    return “blue”
    else
    return “brown”
    end
    end

    — global public method
    function Man.getEyes(args)
    return getEyeColour({hairColour=args.hair})
    end

    — all done
    return Man

    and in main…

    local mark = require(“Man”)
    print(“eyes=” .. mark.getEyes({hair=”brown”}))

  9. Jonathan Beebe says:

    @Mark: There’s really no difference, the reason why I did the two-step is because it’s easier to adapt existing modules, because if you were to add a table prefix to your functions, it could break other code that uses those functions. Doing it in the way I described above, it shouldn’t break any of your existing code within that module because the original functions still exist (you just need to localize them, is really the only thing you have to do with the functions).

    About being global, in your example, when you do:
    local Man = {}
    function Man.getEyes(args) … end

    Man.getEyes is NOT global because getEyes is a key to the table Man, which was localized above. It’s the same concept as forward declarations.

    The two things below are exactly the same, both utilize only locals, so it’s just a matter of personal preference:

    ex. 1:

    local M = {}

    function M.testFunction1() print( “Test 1″ ); end

    is the same as…

    ex. 2:

    local M = {}

    local function testFunction1() print( “Test 1″ ); end
    M.testFunction1 = testFunction1

    ——

    And to answer your question, making a reference to something doesn’t create a global, unless it’s a global you are storing it into. In the examples above, the tables that hold the references are also local, so there’s no difference when everything is returned at the end of the module.

  10. @jonathan: I get what you say about function Man.getEyes being a key in a local table (Man). Thanks for explaining that. I think I’ve confused the function being callable from outside the module with it being global. It is callable (where function getEyeColour isn’t) but they both die when you kill mark (gulp!) as they both belong to the Man table.

  11. John P. Eurich says:

    @Jonathan: I’m very glad to see your post about eliminating the use of “module”, since it is depreciated in Lua 5.2.0. I’ve been using a technique very similar to yours for a couple of months so that my pure Lua code will run in both Lua 5.1.4 and 5.2.0. Once in a while I use iLuaBox on my iPad to develop and test out small pieces of Lua code, and iLuaBox is based on Lua 5.2.0. Thanks, for your post.

  12. lucky for me I am a total n00b and don’t use modules. I am not using director (I know I should) and just wrote my own menu screen/option screen etc and clean things up when done.

    I really don’t know what I am doing most of the time, but I do keep an eye on mem usage, and use that pretty much all the time to ensure I’m not going high.

    The way I code (I have no experience prior to June 2011 of any kind of programming, ever) is I put everything into one main.lua file and then I write a commented table of contents, and then seperate each section with 2 lines one of —- and +++ across.

    Who knows if it’s right, but seems to be working! lol.

    With that said, I’m looking at this as something I want to learn.

    ng

  13. This is so obvious and simple – I do this in Javascript all the time and it never occurred to me to use it in Lua: localize a namespace and use it! Thanks Jonathan and all for this. I was always under the impression that module was safe. Time to update the tutorials.

  14. Jonathan, could you show the modified code (main.lua and examplemodule.lua) to utilize actual values between the two (rather than the print statements).

  15. How do you actually calls functions or variables with this setup. I think i have everything setup like you advised, but now im confused on how to actually call a function or variable from another module. If i have a “mechanics” module, what is the code to call it? thanks

  16. I seem to write my modules very differently to everyone else here. I use the setfenv call to get around the worry of writing to, or creating new global variables.

    I my approach generally follows this format:

    ———–
    local M={}
    modulename=M

    setfenv(1,M)

    function moduleFunction()

    end

    return M
    ——-

    That seems to have worked well for me. It does mean I need to import all the globals I want into locals before the setfenv call (or import _G), but as a Java developer I quite like “declaring” the external modules I want to use.

    I was curious though, does anyone know whether there are any performance hits associated with this approach?

  17. That’s a very important thing! Like Cheetomoskeeto said, I was always under the impression that module was safe. Let me take a deep look on this and a lot os tests to put it on Director. If it would correct memory leaks, it will be the major update on Director 1.5.

    Thanks guys

  18. Can anyone answer this question? :

    –> Like ustimag.in.board changed director, do we have to also change ui lua, beebegames.lua, TextCandy.lua, etc (Other modules/scripts) that we use in our projects, as they have module(…, package.seeall) at the top ?

    Thanks from the UK!

  19. This is an important issue. Rather than jump on-board immediately with Jonathan’s suggestion (no disrespect intended as this blog post is a big step in the right direction), should we not as a community determine the best approach before the Director’s and Particle Candy’s of the Corona World and anyone else contemplating marketing ext libs make wholesale changes to their code bases?

    In recent days I have coded two projects one using Jonathan’s approach above and another using Pop’s approach (above) – but adding the line setmetatable(M, {__index = _G}) for inheritance. I am wondering after reading the LUA docs http://www.lua.org/pil/15.4.html#package-env, whether Pop’s approach is in fact the preferred one. I am studying up on the various approaches to writing externals without using module, and it seemed apparent that if one external developer chooses one method and a second developer an alternative method their products may not play well in the same project.

    Thoughts anyone?

    @Pop, the performance hit (if any) for using inheritance in the manner you describe is simply because you inherit everything in the global array as opposed to inheriting only what you need, which takes more care. I believe it makes a negligible different, but am yet to prove it one way or another.

    Kind regards, Andrew

  20. @Xenon: with the upcoming version 1.0.17, Particle Candy will be rewritten to get rid of the module function (usage and everything else stays the same, of course, so it won’t break any existing code). If you need the updated version asap, just drop a mail and we’ll send it over to you.

  21. Most of the modules I create are for display objects. How can this method you are proposing deal with that situation? How can I return the display object?

    local examplemod = require “examplemodule”
    examplemod.new()
    examplemod.x = 50 –this throws an error

  22. @jon

    There is no real different between the two methods of defining a function, except when using recursive local functions.

    With method #1, you could not call “testfunction” from inside the function because it is only defined at the end of the function.

    In method #2, “testfunction” has already been defined and visible inside the function. Lua expands method #2 to the following:

    local testfunction — forward reference
    testfunction = function(arg)
    ….
    end

    You can read more about this on page 51, Programming in Lua book.

    — Method #1
    local testfunction = function(arg)
    ….
    end

    and

    — Method #2
    local function testfunction(arg)
    ….
    end

  23. Could anyone provide me some feedback on receiving a value back under the new concept. I’m a little new to LUA and would appreciate some help.

    Main.lua
    ———
    local examplemod = require “examplemodule”
    local M = {}
    examplemod.testFunction1()
    print(M[1]) — nil ? Where’s the beef?

    External lua:
    ————–
    — define a local table to store all references to functions/variables
    local M = {}

    — functions are now local:
    local testFunction1 = function()
    M[1] = “very dark” ; M[2] = “dark light”; M[3] = “not dark”
    end
    — assign a reference to the above local function
    M.testFunction1 = testFunction1

    — Finally, return the table to be used locally elsewhere
    return M –return value to caller?

  24. @carlos and anyone who can assist. When I debug main.lua I get: dump M[1] “nil value”

    How do I access the values in M to use them in main.lua? The values are in examplemodule.lua. Help this seems so easy, what’s happening? This easy language has now presented me with a road block in my design – to eliminate memory leaks in my software. Please send the lua swat team.

    Error in expression:
    [string “return (M[1])”]:1: attempt to index global ‘M’ (a nil value)
    stack traceback:
    [string “return (M[1])”]:1: in main chunk
    [C]: in function ‘xpcall’
    ?: in function

    Thanks for responding!

  25. the module function by itself has NOTHING to do with memory “leaks”…your code does…that’s it. With the exception of “weak” tables, a reference is a reference….if your local var = require(‘somemodule’) persists for the life of your app, then the entire token space is preserved in memory regardless of whether or not a tiny pointer to the table exists in package.loaded

    This technique could actually cause WORSE memory leaks because the same code is loaded multiple times into different tables, so that if you don’t CONFIRM that you’ve deferenced your locals to allow them to be GC’d, then you will TRULY leak and VERY fast. Doing any kind of decorating or inheritance in your modules will almost guarantee you hit this problem…

    These techniques are good, but thinking they will solve a memory leak is a red-herring….furthermore, by re-requiring the same source-file over and over again, without letting Lua cache it, you are repeatedly incurring one of Lua’s most expensive operations…the parse and tokenize phase

    hope this helps…

  26. I just wanted to let you guys know that I have updated enhanced ui.lua (to 2.2) with this earlier today. Module function is removed… New code is available at my blog (along with the file download) and the code exchange…

  27. So I updated my own app to use the recently modified versions of ui.lua and particle candy library that have been rewritten to support this new module-less paradigm. When I had the old versions in my app I included them in main.lua with a line like ‘local ui = require( “ui” )’, but now, with the new versions, I have to use a GLOBAL require in order for them to be seen by other modules. As I mentioned above, this seems to defeat the whole “going totally local” purpose of doing away with module().

    Jon suggests I should instead locally require them in every other module that uses them, but Dewey’s comments raise a red flag that seems relevant here. If I include them in every module locally won’t I risk having many multiple versions of the same module clogging up the bloating memory usage and causing memory leaks if I’m not careful to completely remove them.

    Put in the form of a question, how can I include the same lua source file over and over, as Jon is recommending I do, but still make sure lua is caching them, as Dewey says I must do or will get major memory leaks?

    At this point I’m more confused than ever about the best approach to modular programming in lua/Corona.

  28. XenonBL, all….I need to apologize; what I wrote above had a big error in it…it was quite late and I was remembering (incorrectly so) that it was MODULE rather than REQUIRE statement that cache’s the tokenized code in package.loaded. That was wrong…it IS the REQUIRE function that updates package.loaded such that multiple requires should always reference the same originally loaded copy and not leak or re-parse as I had cautioned. It should be reiterated that package.loaded is less “global” than _G is since it doesn’t exist in the scope search path for anything but another call to “require”…you are completely safe to use JB’s technique in full, but don’t expect it to solve any memory leaks for you ;_

    • @Scott: The only benefit is that when you are porting existing modules (that use module), doing it in the way I showed will help reduce the chances of that module’s code breaking (if functions within that module rely on other public functions within that module). Other than that, nope, absolutely no difference really.

  29. Ok, so I’m really lame when it comes to coding, never did anything before lua as I have always said. The code below works, but I’m probably either just lucky, or it’s messy.

    am I interpreting this correctly?

    “local M = {} stores all references to functions and variables”

    How does it do that? Does that mean any function I write will always be stored in M. Maybe I should ask that afterwords, but to my first part of the question is the below correct even though it “works”? :)

    I’m really trying to establish good practices since I had no coding experience before. I know that just because things work, doesn’t mean it’s good. haha,

    let the fun begin!


    -- define a local table to store all references to functions/variables

    local M = {}

    -- functions are now local:

    local redbox = display.newRect (130, 50, 60, 50)
    redbox:setFillColor(255,0,0)

    local greenbox = display.newRect (130, 150, 60, 50)
    greenbox:setFillColor(0,255,0)

    local bluebox = display.newRect (130, 250, 60, 50)
    bluebox:setFillColor(0,0,255)

    local testFunction1 = function(event)
    if event.phase == "began" then
    redbox.alpha = .25
    print( "Test 1 - red box faded" )
    end
    end

    -- assign a reference to the above local function

    M.testFunction1 = testFunction1

    local testFunction2 = function(event)
    if event.phase == "began" then
    greenbox.alpha = .25
    print( "Test 2 - green box faded" )
    end
    end

    M.testFunction2 = testFunction2

    local testFunction3 = function(event)
    if event.phase == "began" then
    bluebox.alpha = .25
    print( "Test 3 - blue box faded" )
    end
    end

    M.testFunction3 = testFunction3

    -- Finally, return the table to be used locally elsewhere

    redbox:addEventListener("touch", testFunction1)
    greenbox:addEventListener("touch", testFunction2)
    bluebox:addEventListener("touch", testFunction3)

    return M

  30. Oh and one more question to the above (no edit button….sadness)

    why is it the eventlisteners in my code only work when placed before “return M” and not after?

    Sorry for the dummy question. I do have books and I am reading them (lua reference and programming in lua 2nd edition) but…yea im noob. :)

    ng

  31. Excellent thread! But I have some questions about what functions to “include” in the new local “M” table.

    Let’s say that I have an external module”popupwindow.lua”. In that module are 3 functions, but only 2 of the modules are “called” from elsewhere, i.e. from main.lua. For example…


    --popupwindow.lua
    local function pauseContent() (my code) end

    local function clearContent() (my code) end

    local function loadContent() (my code) end

    Of these 3 functions, the only function that needs to be “accessible” from outside this module is “loadContent”, and so I would include it in the table “M” as specified…


    --popupwindow.lua
    local M = {}

    local function pauseContent() (my code) end

    local function clearContent() (my code) end

    local function loadContent() (my code) end
    M.loadContent = loadContent

    return M

    This, of course, makes “loadContent” accessible from any other Lua file which requires-in “popupwindown.lua”. But what about the other two functions in the module? They are used only internally within that module… never outside it… but do I still need to add them to table “M” to prevent them from going into the global space?

    Expand this outward to a theoretical module with 15 local functions. If only 3 of those functions need to be accessible from elsewhere, what about the other 12? It seems very tedious if I must include all 12 functions inside “M” even if they’re never used outside the module… but if this is necessary for true optimization, so be it. I’m just trying to gain a better understanding of what’s going on under the hood. :)

    Thanks!
    Brent Sorrentino
    Ignis Design

  32. @Brent: If you don’t want a function (or any variable for that matter) to be publicly accessible to other modules, simply declare it as ‘local’ in your module. That’ll prevent it from being global, and as long as it’s not in the ‘M’ table, it won’t be accessible by other modules either.

    Hope that helps!

  33. Thanks Jonathan! That answers my question exactly. I was hoping that the usage of “require(”)” didn’t somehow place everything in the ‘required-in’ file into the global scope… turns out the culprit was Lua’s “module(…)” function, and I’m pleased that they’re depreciating it. I managed to purely localize my entire app using the new method and it didn’t take long at all.

    Out of curiosity, since you are in closer contact with Ansca, will they depreciate the “module” function in Corona’s core libraries such as the physics and sprite libraries? I don’t know how these are programmed into Corona’s architecture behind the scenes (I don’t really want to know, ha ha), but since the physics/sprite/etc. libraries are required-in, I’m concerned that they utilize the module function, thus placing all associated functions into the global scope. :( However I don’t pretend to understand the core architecture behind Corona, and I leave it to Ansca’s good judgment to do what’s necessary regarding the depreciation of “module(…)”.

    Brent

  34. So how do you get a constructor out of this new setup?

    Say I want to be able to do this do this:

    local b1 = newBall(“red”);
    local b2 = newBall(“blue”);

    The only way I have got this going without modules so far is to do this:
    function newBall(_color)

    local ball = {}

    ball.color = _color
    ball.state = “full”

    local bounce = function()
    print(“bouncing”);
    end
    ball.bounce = bounce

    local empty = function()
    ball.state = “empty”;
    end
    ball.empty = empty

    — Finally, return the table to be used locally elsewhere
    return ball
    end

    And my main.lua file looks like this , that I actually tested with:

    local BallFactory = require(“Ball”)

    local b1 = newBall(“red”)
    local b2 = newBall(“blue”)

    –Make sure we have two distinct objects created
    print(b1.color)
    print(b2.color)
    print(b1.color)
    print(b2.color)

    b1:bounce()
    print(b1.state)
    b1:empty()
    print(b1.state)

    Thanks
    Bob

  35. Appears the scope of is global this
    local BallFactory = require(“Ball”)
    or require(“Ball”) will work when I run my main.lua file. Is this bad? Is that the beast I’m trying to defeat?

  36. How can you clear memory?
    If a menu page memusage is say 200, then memusage goes up to say 350 after changing scenes, surely it should go back to 200 when changing back to menu page.
    Here is an example, has anyone got a way to clear the information held by require?

    -- main.lua
    display.setStatusBar( display.HiddenStatusBar )

    local menu = require( "menu" )

    menu.runMenu()

    --menu.lua
    local menuTab ={}

    menuTab.runMenu = function()
    menuGroup = display.newGroup()

    local monitorMem = function()
    collectgarbage("collect")
    print( "nMemUsage: " .. collectgarbage("count") )
    local textMem = system.getInfo( "textureMemoryUsed" ) / 1000000
    print( "TexMem: " .. textMem )
    end

    local closeMenu = function()
    display.remove(Atext)
    Atext = nil
    display.remove(Atext2)
    Atext2 = nil
    display.remove(menuGroup)
    menuGroup = nil
    shez1 = require("shez1")
    shez1.runShez1()
    timer.performWithDelay(2, function() collectgarbage("collect") end)

    end

    local Atext = display.newText( "Goto shez1",
    display.viewableContentWidth*0.25,
    display.viewableContentHeight*0.44,
    native.systemFontBold, 36)
    Atext:setTextColor(255, 255, 255)
    menuGroup:insert(Atext)
    Atext:addEventListener( "tap", closeMenu)

    local Atext2 = display.newText( "Press for memory",
    display.viewableContentWidth*0.25,
    display.viewableContentHeight*0.64,
    native.systemFontBold, 36)
    Atext2:setTextColor(255, 255, 255)
    menuGroup:insert(Atext2)
    Atext2:addEventListener( "tap", monitorMem)

    end

    return menuTab

    --shez1.lua
    local shezTab ={}

    shezTab.runShez1 = function()
    shez1Group = display.newGroup()

    local closeShez = function()
    display.remove(Btext)
    Btext = nil
    display.remove(shez1Group)
    shez1Group = nil
    local menu = require("menu")
    menu.runMenu()

    timer.performWithDelay(2, function() collectgarbage("collect") end)

    end

    local Btext = display.newText( "Goto Menu",
    display.viewableContentWidth*0.25,
    display.viewableContentHeight*0.44,
    native.systemFontBold, 36)
    Btext:setTextColor(255, 255, 255)
    shez1Group:insert(Btext)
    Btext:addEventListener( "tap", closeShez)
    end

    return shezTab

    Am I worrying too much about this memory staying there?
    I have tried different scene changing libs (director etc) but always get the same problem.
    Many Thanks.

  37. Nevin Flanagan says:

    Because there was some question raised above, regarding the use of “local foo = function()” vs. “local function foo()”, I compiled both versions to Lua bytecode. The outputs were literally identical.

    [code]– define a local table to store all references to functions/variables
    local M = {}

    — functions are now local:
    local testFunction1 = function()
    print( “Test 1″ )
    end
    — assign a reference to the above local function
    M.testFunction1 = testFunction1

    local testFunction2 = function()
    print( “Test 2″ )
    end
    M.testFunction2 = testFunction2

    local testFunction3 = function()
    print( “Test 3″ )
    end
    M.testFunction3 = testFunction3

    — Finally, return the table to be used locally elsewhere
    return M[/code]

    [code]– define a local table to store all references to functions/variables
    local M = {}

    — functions are now local:
    local function testFunction1()
    print( “Test 1″ )
    end
    — assign a reference to the above local function
    M.testFunction1 = testFunction1

    local function testFunction2()
    print( “Test 2″ )
    end
    M.testFunction2 = testFunction2

    local function testFunction3()
    print( “Test 3″ )
    end
    M.testFunction3 = testFunction3

    — Finally, return the table to be used locally elsewhere
    return M

    [/code]

  38. @Nevin,

    You’re right that the two ways of defining the functions are identical EXCEPT if you need to call the function within the same function (recursive call).

    The method: local function testfunction(arg) is callable within the defined function where local testfunction = function(arg) is not.

  39. I have performance issues after changing my code in this way @Jonathan Beebe

    everything works fine but the problem is performance is too slow in real device (android os ) my old code on real device in module run fast also 30 fps is working correctly but after changing my code in that way the game start with 15 fps and memory is the same usage please help me if there is way to know where is the memory leaks in my code so i can change it ..

    thanks in advance

  40. This technique reminds me of the Asynchronous Module Definition used in modern JavaScript libraries. However, since “require()” assigns “package.loaded[modulename]” to the loaded module’s exports this means that all modules are loaded into the same “context” (i.e. the global context — ‘package.loaded’). A more robust approach would have support for contexts, such that modules can import/require other modules into a new context, thereby allowing different versions of modules to coexist.

    For a module that permits loading context aware modules see my Context Lua module ( https://github.com/dschnare/Context-Lua. ) and its example.

    Regarding Mohammad’s performance issues: The modules that are “required/imported” are loaded and executed if and only if they haven’t been loaded already in the loading context (without context-lua this will always be the global context). Requiring a module more than once will simply return its exports, which is much faster than having to load and execute every time. Can you offer an example where this is happening for you?

    Perhaps Lua does some code optimization for modules defined using the “module()” function, which may explain why code using said the “module()” function appears to execute faster. Does anyone know anything about this?

  41. Chapter 15 of the Lua book explains how the module function is derived from the code shown above. After going through that chapter I have the feeling that the module function really is what we want. Am I missing something?


  42. local M = {}
    function M:testFunction2()
    print( "Test 2" )
    end
    return M

    1.) Is this function local to M={} or to the file itself, OR is it global at all?
    2.) So, do I correct understand, that this function is a branch of M={}?
    2.2) Where does it belong to in the M table? Is it like M={testFunction2()} or like M={testFunction2 = ()} or M={testFunction2 = testFunction2()}??

    • Jonathan Beebe says:

      @jack0088: Correct, M:testFunction2() is the same as M.testFunction2( self ) … so yes, testFunction2 is local because it belongs to ‘M’, and ‘M’ is local.

  43. I’ve been having some issues with implementing this method – down solely to my inexperience. I’ve posted a question on the forums here: http://developer.anscamobile.com/forum/2011/11/18/few-quick-questions-understanding-modules

    I’ve posted the link as I don’t want to post the sam info here and clog up this thread, but I’d be grateful if @Jonathan Beebe or anyone else can help me out with this as at present it has halted my development.

    • Srdjan,

      if the function in main is global then _G.funname() in the module does the job
      if you don’t want to have a global function, you can add a runtime listener in main and dispatch an event in the module

  44. Hi,
    Great tutorial, thanks Jonathan.

    A question : Why don’t we use this technic … :

    — define a local table to store all references to functions/variables
    local M = {}
    ….
    — assign a reference to the above local function
    M.new = new
    — Finally, return the table to be used locally elsewhere
    return M

    …for Storyboard?

    Thank you for your answer
    Olivier

  45. Hi, I just started using Corona and stumbled on this page when looking for better organization of our code.
    Does this modular approach still hold in the current builds? Or is it not necessary anymore?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>