[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Relative Requires in Lua
- From: "Soni L." <fakedme@...>
- Date: Thu, 13 Oct 2016 16:28:49 -0300
Disclaimer: If this sounds like a blog post, that's because this is a
blog post. (Should blog posts be tagged somehow? Say, [BP] or something?)
Lua's most overlooked feature is the require function. People assume it
just loads a file and returns whatever it loaded. But it does a lot more
than that.
For one, it implements a cache. You can require the same module over and
over and it'll always return the same value. While this doesn't get
overlooked often, I've seen people implement a cache on top of the
standard require()... or attempt to reload a module with the standard
require() .-.
However, you can override this by fiddling with the contents of
package.loaded.
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.
This "relative require" pattern is never mentioned in Programming in
Lua, 3rd edition, which's a bit of a shame. It seems most Lua users
don't know about this - even those who have worked with Lua extensively.
Don't make a searcher that supports `require"./name"`, as that'll just
get cached as "./name". Make a searcher that supports
`require(modname..".name")` instead, where `modname` comes from `...`.
This might be a new pattern to you, but it's a very useful pattern. I
use it all the time with my oversized modules, precisely because it
supports renaming.
There are a few other things require does that I'm not gonna go into.
This isn't supposed to be a complete tutorial on modules - unlike the
modules section of PiL (which I think should include this, however I
don't have PiL 4 to check). But this is the basic idea of relative require.
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.