Lua 程式設計教學:模組 (Module)

PUBLISHED ON FEB 25, 2018 — PROGRAMMING

    在先前的章節中,我們都將程式碼寫在同一個檔案中,隨著專案規模上升,若我們仍然用這種方式撰寫程式碼,程式碼會變得很長而不易維護。將程式碼依照功能拆開在不同的模組中,對於專案的維護會較佳。

    我們在前文中提過,Lua 是一個內嵌語言,可用的套件較其他語言來得少,而且會隨著宿主軟體而有所不同;通常會在宿主軟體中透過外掛 (plugins) 的方式來延伸 Lua 的功能。有些功能,像是某個遊戲所需的規則和人工智能,會隨著不同遊戲而異,不太會由宿主軟體提供。通常程式設計者會自行撰寫一些模組,再自行呼叫該模組。

    撰寫模組

    我們直接以實例展示如何撰寫 Lua 模組:

    -- point.lua
    local Point = {}
    package.loaded["Point"] = Point
    
    Point.__index = Point
    
    function Point:new(x, y)
        self = {}
        self._x = x
        self._y = y
    
        setmetatable(self, Point)
        
        return self
    end
    
    function Point:x()
        return self._x
    end
    
    function Point:y()
        return self._y
    end
    
    return Point

    一個模組包含單一類別,而類別的撰寫方式如同前文所述。一般來說,我們會將物件寫在一個表 (table) 中。雖然在使用表時,無法區分公有和私有的屬性和方法,但這不是 Lua 程式的重點,不用在這個環節上過度計較。

    通常在第二行會加上 package.loaded[...] = ... 的敘述,告訴 Lua 將此模組載入。

    常見的手法是將 __index 這個 metamethod 指向物件本身。這樣的意義在於當 Lua 找不到某個特定屬性或函式時,會從該物件的表中去查找。

    接下來就如同一般寫物件的方式,此處不再重覆。

    在最後一行會將此類別回傳,待外部程式呼叫。在模組內也可以呼叫其他模組,在下一段介紹如何呼叫模組。

    使用模組

    承接以上的例子,我們直接以實例展示如何呼叫模組:

    local point = require("point")
    
    local p = point:new(3, 4)
    
    assert(p:x() == 3)
    assert(p:y() == 4)

    使用 require 即可呼叫模組,預設情形下,模組和主程式位在同一個資料夾。若模組位於子目錄下,則略為修改 require 的位置即可,如下:

    local point = require("lib.point")
    
    -- Same as above.
    comments powered by Disqus