lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 13.10.2016 um 21:28 schröbte Soni L.:

For two, Lua's module system fully supports relative requires. This is
one of the most overlooked features of Lua! I see people doing `local
submod = require "thismod.submod"` all the time. That's not how you do it!

The proper way to do relative requires is:

thismod/init.lua
-----
local modname = ...
local submod = require(modname .. ".submod")
return {submod=submod}
-----

thismod/submod.lua
-----
return {
  helloworld = function() print("Hello World!") end
}
-----

Then, if you require "thismod", you can call
thismod.submod.helloworld(). However, if you rename the thismod
directory, and require the new directory name, it'll still work! Unlike
when using hardcoded module names.

I think relative `require` is an anti-pattern for the following reasons:

1. The module name is part of the public interface, so you shouldn't rename it at all (or at least bump the major version number afterwards).

2. If you move a module `a.x` to `a.s.x`, all relative `require`s in this module *and of* this module break. With absolute `require` only the `require`s *of* this module need to be fixed.

3. It only works for internal modules that are never `require`d from the outside or else the renaming feature stops working anyway.

4.  It leads to bloat. For modules like

        return { -- file a.lua
          b = require( ... .. ".b" ),
          c = require( ... .. ".c" ),
          -- ...
        }

`local a = require("a")` will load all submodules even if only a few of those modules are actually needed.

5.  The interface gets uglier as well:

        local a = require( "a" )
        a.b.u.x.func()

    compared to

        local x = require( "a.b.u.x" )
        x.func()

6. You can run into `require` cycles if module `a.b.u.x` needs functions from module `a.b` but should also be part of it.

Philipp