Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I structure a self-contained module in Lua?

I'm making a Lua library for Love2D, which contains quite a bit of internal sub-modules, class files, and the like.

What I'm doing now looks like this:

File ./libname/init.lua
lib.prefix = (...):match("(.-)[^%.]+$") .. "libname."
lib = {}

lib.class = require(lib.prefix .. "lib.class")
lib.types.Blah = require(lib.prefix .. "types.Blah")

return lib
File ./libname/types/Blah.lua
local Blah = lib.class()
...
return Blah

Except the thing here is that lib is a global, and if I make it into a local, I cannot properly structure the submodules like Blah, because they no longer have access to the lib table.

This is obviously a stripped down example, but I think it demonstrates my problem well - I would like to make the lib table local, and return it, so that inclusion of the library goes like lib = require "libs.libname", rather than have the whole thing imported into the global scope when I require the module itself. Is it possible?

like image 541
Llamageddon Avatar asked Sep 03 '25 03:09

Llamageddon


1 Answers

I made a guide for this very concept. You can find it here:

http://kiki.to/blog/2014/03/30/a-guide-to-authoring-lua-modules/

To solve the specific problem that you mention in your question, I would use 3 files: core.lua to share the state, the "real files" which change the core, and init to tie everything up.

./libname/core.lua is where lib is defined, as a local bar. It does not define lib.types. It "sets the ground up" with utilities that other files might want to use, like setting up a prefix or a utility class.

local lib = {}

lib.prefix = (...):match("(.-)[^%.]+$") .. "libname."

lib.class = require(lib.prefix .. "lib.class")

return lib

The 'regular files', like ./libname/types/Blah.lua, use those utilities, but don't modify lib at all:

local lib = require 'core' -- or libname.core or using the current_folder trick

local Blah = lib.class()
...
return Blah

init.lua binds everything together:

local lib = require 'core' -- or libname.core or current_folder trick

lib.types.Blah = require(lib.prefix .. "types.Blah")

return lib

The "current folder trick" mentioned in the comments is here: http://kiki.to/blog/2014/04/12/rule-5-beware-of-multiple-files/#the-current_folder-trick

like image 92
kikito Avatar answered Sep 05 '25 01:09

kikito