Modules: The Module keyword
Contents
There are various ways to add a Lua module in Iguana. See our recommended approach.
This page explores some of the issues with other approaches, it is kept as a resource for explaining the thought process we went through in coming up with what we think is a good approach. If you are busy you can stop reading here.
Iguana annotations are helpful in graphically showing some of issues with other approaches.
Using the module(…,package.seeall) syntax when defining modules is frequently used in Lua, but it does cause some unusual scoping side effects. However the scoping problems are not a major issue as you can see from the example 3 below (though a malicious programmer could certainly break other modules). We should not overly malign module(…,package.seeall) as similar effects can happen without it (see example 2).
A little background: Lua uses a global environment table _G , which contains all global variables, functions, tables etc. So global variable myVar=_G.myVar, table myTable=_G.myTable and function myFunction=_G.myFunction. Depending on how modules are defined you will expose more or less detail globally in the _G table.
We will show three approaches using modules test1, test2 and test3.
- Completely private module (test1)
- Create a module using a local table and return that table as the interface
- Place all functions etc in that table
- Local variables are completely private, not available in _G
- You must use returned table as the interface to reference the module
- Module name exposed globally (test2)
- Create a module with a global table as the interface
- Insert all functions etc in that table
- The global table is used as the interface for the module
- Module name exposed globally and allow function global access (test3)
- Use the “module(…, package.seeall)” function in the module, inherits all of _G
- Very similar to test2, but with a few extra side effects…
Note: the function declaration syntax used would create global functions in test1 and test2
Completely private module (test1)
main:
test1:
Module name exposed globally (test2)
Notice how test2 can access modules test3, and test4, test 3 uses module(…,package.seeall) declaration, test4 uses an identical declaration to test2. Not the best in theory, but will it ever cause practical issues?
main:
test2:
Module name exposed globally and allow function global access (test3)
I included some more examples of scoping issues when using the module(…,package.seeall) syntax. But once again do they cause a practical problem?
main:
test3:
__index from metatable for test3:
So if you were wondering what the module(…,package.seeall) does then look at this annotation. This is the metatable for test3, it has one entry __index, which turns out to be identical to _G. The __index metamethod (or table in this case) is checked when an attempt is made to access an absent field in a table, if a match is found then it is returned. This is how Lua does inheritance, and in this case how test3 inherits all of _G.
There is a lot of online discussion about how to create modules in Lua, and the potential for side effects, particularly when using module(…,package.seeall). If you are interested you can start with these two links: http://lua-users.org/wiki/ModuleDefinition and http://lua-users.org/wiki/LuaModuleFunctionCritiqued,
One thing is clear, Iguana annotations show you exactly what is happening.