2016-11-10 62 views
1

我想要一次需要幾個Lua模塊,類似於Java中的星號指示符(import java.awt.*)。這個結構我在子目錄中組織了我模塊:如何在一個語句中需要多個模塊?

<myapp> 
-- calculations 
    -- calc1 
    -- calc2 
    -- calc3 
-- helper 
    -- help1 
    -- help2 
    -- print 
      --graphprinter 
      --matrixprinter 

我的客戶需要一個子路徑的每個模塊:

local graphprinter = require("myapp.helper.print.graphprinter") 
local matrixprinter = require("myapp.helper.print.matrixprinter") 

我寧願一個自動多要求,從派生本地表名模塊路徑並且需要一次完整的子路徑。這可能是格式:require("myapp.helper.print.*")。應該爲子目錄的每個模塊自動創建本地表名,這樣就不會有任何區別,因爲我一直需要按模塊進行。

+1

Lua無法獲取文件夾中所有文件的列表,因此無法獲取模塊列表。但是你可以編寫一個腳本來獲取模塊列表,方法是用'io.popen「ls ...」'發出shell命令,然後'require()'找到所有模塊。 –

+1

還有重新創建不能在模塊中創建全局變量。因此,即使您可以加載所有模塊值,也無法獲得模塊值。所以,可能只是讓單獨的文件至極做負載加載值表中的所有需要​​的值並返回。 – moteus

回答

1

該模塊env部分實現你正在尋找的東西,雖然它遠非完美。

它允許分組/命名導入,但有一些注意事項 - 主要是您必須手動管理您的環境。此外,您需要編寫索引文件(默認init.lua,除非您編寫自定義路徑集),因爲它旨在用於導出表的模塊。

這是一個例子。首先,我們需要正確設置我們的文件結構。

-- main.lua 
-- calculations/
    -- calc1.lua 
    -- calc2.lua 
    -- calc3.lua 
    -- init.lua 
-- helper/
    -- print/
      -- init.lua 
      -- graphprinter.lua 
      -- matrixprinter.lua 

索引文件,這是稍微繁瑣:

-- calculations/init 
return { 
    calc1 = require 'calculations.calc1', 
    calc2 = require 'calculations.calc2', 
    calc3 = require 'calculations.calc3' 
} 

-- helpers/print/init 
return { 
    graphprinter = require 'helper.print.graphprinter', 
    matrixprinter = require 'helper.print.matrixprinter' 
} 

內,您的主文件。主要的注意事項很快顯示出來,您必須使用通過要求'env'覆蓋您的本地環境返回的功能。傳遞任何參數都會創建當前環境的克隆(保留require等)。

-- main.lua 
local _ENV = require 'env'() -- (see notes below) 

新的環境將給出一個import函數,它只有一個參數,字符串代表路徑模塊名稱導入到當前的環境。返回值是一個可以用來進一步改變環境狀態的瞬態表。

import 'helper/print' :use '*' 
import 'calculations' :use '*' 

一對瞬態表的功能是:use,這無論是將表指示哪些值從所需的表拉,或串'*',這表明你想從所需的表中的所有值擺在當前的環境

print(matrixprinter, graphprinter) --> function: 0x{...} function: 0x{...} (or so) 

最後需要注意的是,所有你見過的路徑是在cwd是相同的作爲保持main.lua的一個依賴。 lua myapp/main.lua將會大聲失敗,除非您將子模塊放置在靜態位置,並且正確調整package.path/import.paths

似乎很多工作,以避免幾行require陳述。


免責聲明:我寫了env作爲一個有點實驗。

注意import目前不支持.語法(您需要使用您的操作系統的路徑分隔符),或適當爆炸表到錶鏈。我在解決這個問題的作品中有一點補丁。

Lua 5.2+使用_ENV覆蓋本地環境。對於Lua 5.1,您需要使用​​。


如上所述,Lua沒有真正的目錄概念。爲了真正做到你想要的(用更少的開銷),你需要編寫你自己的定製模塊加載器,環境處理器,並且可能使用像LuaFileSystem這樣的模塊來可靠地'自動'加載目錄中的所有文件。


TL; DR:

  • 這是一個棘手的話題。
  • 語言中沒有任何東西可以使這一點變得簡單。
  • 你需要寫一些自定義的東西。
  • 總會有缺點。
4

爲什麼不爲每個需要所有其他庫的文件夾編寫一個init.lua文件?

例如,在計算你寫一個包含

return { 
    calc1 = require "calc1"; 
    calc2 = require "calc2"; 
    calc3 = require "calc3"; 
} 

文件,然後你可以只寫calculations = require "calculations",它會自動加載calculations.calc<1-3>

這可以爲整個目錄結構來完成,並require "helper"可以撥打require "help1",然後調用require "print",最後您可以在helper.help1.print.<function>中找到您的功能

這是如何工作的簡短說明:當您運行require "library"時,lua將嘗試包含名爲library.lua的文件或位於library目錄中的文件init.lua。這也是你做require "dir.lib"而不是require "dir/lib"的原因;因爲如果做得對,當你只需要require "dir"時,它將返回一個包含字段lib的表格,因此您可以將其作爲​​進行訪問。