wsha
wsha

Reputation: 964

load several Lua modules with single require

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

Answers (4)

wsha
wsha

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

siffiejoe
siffiejoe

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

Egor Skriptunoff
Egor Skriptunoff

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

Alban Linard
Alban Linard

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

Related Questions