美思 [Lua] 程式設計教學:建立和使用模組 (Module)

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

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

我們在前文中提過,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")

local p = point:new(3, 4)

assert(p:x() == 3)
assert(p:y() == 4)
關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。