Why is my require ‘mymodule’ statement not working?

Introduction [top]

The require statement is used to include modules in a script. There are various different ways to structure a module. Depending on how the module is structured you have to use the require() statement a bit differently.

So why don’t we just stick to the standard Lua module structure? First because Lua is a very flexible language there is no “standard” module structure. Second when we started using Lua we used the common module(...,package.seeall) syntax (which it turned out does not play well with annotations in the Translator). So we then moved on to other methods as described in Background and history below.

Tip: If you see require('mymodule') it is just an alternative syntax for require 'mymodule' the two perform identically and are interchangeable.

The quickest way to solve the issue [top]

There are two ways you can use the return() statement, if one doesn’t work the other will.

  • require 'mymodule'
  • local MM = require 'mymodule' -- you can use any name for the variable

Background and history [top]

These are three commonly used Lua module structures, see Modules: Structure for more information on their advantages and disadvantages.

  1. Recommended best practice: Module with a local table interface with a return statement at the end of the module, this is the method recommended by the Lua committee
  2. Good: Module with a global table interface, this method has now been deprecated by the Lua committee
  3. Do not use: Use module(...,package.seeall) syntax, this is an older method with definite disadvantages

Historically we started off using method 3 then 2 and finally 1. Many of our modules still use method 2. As far as I am aware there are no longer any modules with method 3. Therefore we will only address how method 2 and 3 work with require().

We also use a hybrid of one and two, call it method 1.5. This is where we use a global interface table and a return statement. This is probably the most common module structure we use.

Tip: If you want to make you head hurt, there are many more ways to create modules in Lua!

How does it work? [top]

The require() statement is actually just a function supplied with Lua. It is used to load and run your modules (basically it just runs the code in the module).

This give you two critical things:

  1. A return statement can be used at the end of the module to return a variable from require()
  2. You can use see any global variable and functions in the module

So again how does it work? Ok let me explain…

Method 1: Module with a local table interface and a return

This method relies on using a return statement to return the “interface table” of functions at the end of the module. There are no global (public) variables or functions in the module, so the only way the functions can be accessed is through the returned interface table.

Here is how to use require with this type of module:

local MM = require 'mymodule'
local fred = require 'mymodule' -- this also works because you can use any name for the local variable

function main()
   MM.helloWorld()
   fred.helloWorld()
end

Method 2: Module with a global table interface

This method uses a global “interface table” to expose the interfaces in the module. There is no return statement the functions are accessed by referencing them through the interface table.
Note: The interface table must have exactly the same name as the module.

Here is how to use require with this type of module:

require 'mymodule'

function main()
   mymodule.helloWorld()
end

Method 1.5: Hybrid module with a global table interface and a return statement

This method uses a global “interface table” to expose the interfaces in the module and a return statement to return the “interface table” of functions at the end of the module. You can access the returned interface table, or through the by referencing them through the public interface table.

This allows you to use the syntax from method 1 and method 2, which means no matter how you use require it works (basically the “lazy interface”).

Here is how to use require with this type of module:

-- Method 1 syntax works
local MM = require 'mymodule'
local fred = require 'mymodule' -- this also works because you can use any name for the local variable

-- Method 2 syntax also works
require 'mymodule'

function main()
   MM.helloWorld()
   fred.helloWorld()
   mymodule.helloWorld()
end

Example with pictures [top]

We will start with a method 1 module, change it to method 2 and then method 1.5. We will show how each one works as well the errors from common mistakes (and how to fix them).

Method 1: Module with a local table interface and a return

Here is the code from main() using different variables, both work fine:

This is the module, notice how the interface table mymodule is local and is returned on the last line of the module:

So lets try the method 2 syntax, and it fails saying that mymodule is nil (which is as expected as nothing is returned from the module):

How to fix it?

  • Revert the call in main() to the method 1 syntax (in the first picture above)
  • Make the mymodule variable global  (converts it to “Method 1.5” below)
  • Make the mymodule variable global and remove the return statement (converts it to Method 2 below)

Method 2: Module with a global table interface

Note: The interface table must have exactly the same name as the module.

Here is the code from main():

This is the module, notice how the interface table mymodule is global and is no longer returned on the last line of the module:

So lets try the method 1 syntax, and it fails saying that mymodule is boolean (which means that the require() worked and returned “true” – which doesn’t help much):

An interesting thing to note is that our “method 2” call still works, which makes sense because require() still exposes the global mymodule.

How to fix it?

  • Revert the call in main() to the method 2 syntax (in the first picture)
  • Add the return statement on the last line of the module (converts to “Method 1.5” below)
  • Add the return statement on the last line of the module and make the mymodule variable global (converts to Method 1 above)

Method 1.5: Hybrid module with a global table interface and a return statement

This allows you to use the syntax from method 1 and method 2, which means no matter how you use require it works (basically the “lazy interface”).

Here is the code from main(), as you can see both methods work:
Screen Shot 2014-09-09 at 16.51.54

This is the module, notice how the interface table mymodule is global and also returned on the last line of the module:
Screen Shot 2014-09-09 at 16.53.56

How to fix it?

  • Nothing to fix…

Note: While this might seem the ideal solution the method 1 is actually the best  structure (as it keeps the module functions private), see Modules: Structure for more information.