In Lua how do you import modules?

61,656

Solution 1

Either of them works. Storing it in a local will not change the fact that the module may have registered global functions.

Solution 2

Some libraries work only one way, and some only work the other way

The require "name" syntax was the one introduced in lua 5.1; as a note; this call does not always return the module; but it was expected a global would be created with the name of the library (so, you now have a _G.name to use the library with). eg, earlier versions of gsl-if you did local draw = require"draw" the local draw would contain true; and shadow the global draw created by the library.

The behaviour above is encouraged by the module function ==> now relatively deprecated, any well written new code will not use it.

The local name = require"name" syntax became preferred recently (about 2008?); when it was decided that modules setting any globals for you was a bad thing. As a point: all my libraries do not set globals, and just return a table of functions; or in some other cases, they return an function that works as an initialiser for the root object.

tldr; In new code, you should use the latter local name = require"name" syntax; it works in the vast majority of cases, but if you're working with some older modules, they may not support it, and you'll have to just use require"module".


To answer your added question: do you require the system modules?: no; you just assume they are already required; but I do localise all functions I use (usually grouped into lines by the module they came from), including those from external libraries. This allows you to easily see which functions your code actually relies on; as well as removing all GETGLOBALs from your bytecode.

Edit: localising functions is now discouraged. To find accidental globals use a linter like luacheck

Sample module in (my) preferred style; will only work with the local name = require"name" syntax.

local my_lib = require"my_lib"

local function foo()
    print("foo")
end

local function bar()
    print("bar", my_lib.new())
end

return {
    foo = foo;
    bar = bar;
}

Solution 3

I would say it mainly boils down to what you prefer, but there are some exceptions depending on what you are writing. Creating a local reference will gain you some speed, but in most cases this isn't a meaningful optimization to do. You should also point your local to the function you are using and not the module table.

If you are writing on a library then I would recommend creating local references for all the global variables you use. Even if you aren’t using the module() function, which changes the global scope for the code that follows. The reason for this is that it prevents your library from calling globals which have been altered after the library was loaded.

Doing local io = require’io’ will ensure you that you get the table from package.loaded.io, even if _G.io has been replaced by another table. I generally don’t do this myself. I expect io to already be loaded and unmodified when I write Lua.

You also have to remember that there are several ways to write a Lua module. Some modules don't return their module table, while others don't create any global variable. The most common solution is to both create and return a global, but you can't always rely on this.

Share:
61,656
Vitaly
Author by

Vitaly

Updated on November 16, 2020

Comments

  • Vitaly
    Vitaly over 3 years

    Do you use

    require "name"
    

    or

    local name = require "name"
    

    Also, do you explicitly declare system modules as local variables? E.g.

    local io = require "io"
    

    Please explain your choice.

    Programming in Lua 2ed says "if she prefers to use a shorter name for a module, she can set a local name for it" and nothing about local m = require "mod" being faster than require "mod". If there's no difference I'd rather use the cleaner require "mod" declaration and wouldn't bother writing declarations for pre-loaded system modules.

  • Vitaly
    Vitaly over 12 years
    But will storing it in a local give you a meaningful speed advantage?
  • Nicol Bolas
    Nicol Bolas over 12 years
    @Vitaly: It depends on what you're doing as to whether or not any speed advantage is meaningful. How often are you calling those functions per-frame? Is the code in question even a bottleneck?
  • Vitaly
    Vitaly over 12 years
    I actually don't do anything in enterFrame event and use timer and transition APIs of Corona SDK, so there's likely no performance advantage in my case. Thanks for clarifying this.
  • Vitaly
    Vitaly over 12 years
    So do you suggest using the alternative proposed here: lua-users.org/wiki/LuaModuleFunctionCritiqued
  • daurnimator
    daurnimator over 12 years
    I suggest coding modules like: local print,tblconcat = print,table.concat; local function foo () return tblconcat({1,2,3}) end; local function bar(...) print("bar",...) end; return { foo = foo; bar = bar }