【问题标题】:load several Lua modules with single require使用单个 require 加载多个 Lua 模块
【发布时间】:2017-09-23 08:36:28
【问题描述】:

我遇到了一个简单的问题,即在没有明确要求所有模块的情况下加载多个模块。
我的模块是寄存器地址和默认值表

这是目录结构,每个模块都包含一个表(与模块本身同名) i-g A01.lua 有 A01 = {} 等等

 main.lua
 map/registers/A01.lua
 map/registers/B20.lua
 map/registers/C31.lua  -- [100+]
 map/registers/XYZ0119.lua

我可以使用加载单个模块

local regMap = require('map.registers.A01')
regMap = require('map.registers.B20') -- and so on

但这不是最优的,因为我有 100 多个。他们将被覆盖

有没有办法一次性全部导入?
或者有没有办法根据“需要”加载某个表?

【问题讨论】:

    标签: lua


    【解决方案1】:

    这是对 Alban Linard 答案的“翻拍”,但没有使用外部库。

    -- 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
    

    【讨论】:

    • 为什么不简单地ls map/registers/*.lua
    • @lhf - 在 mkdir map/registers/Misc_Modules.lua;touch map/registers/Misc_Modules.lua/some_module.lua 之后 require 会尝试加载 some_module 并且会失败
    • 我的想法是在我需要上述任何文件的寄存器名称之一时加载模块。
    【解决方案2】:

    您可以使用luafilesystem 模块来遍历map/registers/ 目录中的文件,然后它们会加载模块:

    -- 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
    

    请注意,name = name:sub (1, #name-4) 删除了扩展名,但我们没有检查它是否是 .lua 文件。

    【讨论】:

    • 这种方法很聪明,但我更喜欢使用元表。
    • 是的,使用元表更适合您的问题的最后一个版本;-)
    【解决方案3】:

    这可能不是你的想法,但我会这样做:

    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
    

    然后使用

    require("map.registers.all")
    

    在您的代码中。

    【讨论】:

      【解决方案4】:

      这是我的解决方案:

         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']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-31
        • 2012-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-04
        • 2014-11-29
        • 2013-05-16
        相关资源
        最近更新 更多