Reputation: 964
I am stuck on a Simple problem of loading several modules without explicitly requiring all of them.
My modules are tables of register address and default values
Here is the directory structure and each module contains a table(same name as module itself) i-g A01.lua has A01 = {} and so on
main.lua
map/registers/A01.lua
map/registers/B20.lua
map/registers/C31.lua -- [100+]
map/registers/XYZ0119.lua
I can load individual modules by using
local regMap = require('map.registers.A01')
regMap = require('map.registers.B20') -- and so on
But this is not optimal, Since I have 100s of them. and they will be over written
Is there any way to import all of them at once?
or Is there any way to load a certain table on "need" basis?
Upvotes: 1
Views: 1383
Reputation: 964
Here is my solution for this:
local regMap = {} -- Define Master table
-- Load a module whenever missing filed appears
setmetatable(regMap,{__index = function (t, k)
t[k] = require ('map.registers.' .. k)
return t[k]
end})
-- Call any module
regMap['A01']
regMap['B20']
Upvotes: 0
Reputation: 4271
This is probably not what you had in mind, but I would do:
rm -f map/registers/all.lua
( for f in map/registers/*.lua; do f="$( basename "$f" .lua )"; echo "require('map.registers.$f')"; done ) > map/registers/all.lua
And then use
require("map.registers.all")
in your code.
Upvotes: 0
Reputation: 23767
This is a "remake" of Alban Linard's answer but without using external libraries.
-- Assume that all your files are inside "map/registers" folder
-- (no recursive subdirectories search is performed)
for filename in io.popen('ls -pUqAL "map/registers"'):lines() do --Linux
--for filename in io.popen('dir /b/a-d "map\\registers"'):lines() do --Windows
filename = filename:match"^(.*)%.lua$"
if filename then
require("map.registers."..filename)
end
end
Upvotes: 2
Reputation: 1047
You can use the luafilesystem
module to iterate over the files in the map/registers/
directory, and they load the modules:
-- Luafilesystem allows to iterate over a directory.
local Lfs = require "lfs"
-- for each filename in the directory
for filename in Lfs.dir "./map/registers/" do
-- if it is a file
if Lfs.attributes ("./map/registers/" .. filename, "mode") == "file" then
-- transform the filename into a module name
local name = "map/registers/" .. filename
name = name:sub (1, #name-4)
name = name:gsub ("/", ".")
-- and require it
require (name)
end
end
Note that name = name:sub (1, #name-4)
removes the extension, but we do not have checked that it is a .lua
file.
Upvotes: 1