第一版是針對 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您也可以幫助支援 Lua 專案


13.3 – 函式庫定義的元方法

一些函式庫定義自己的元表欄位是一種常見做法。到目前為止,我們看過的所有元方法都是針對 Lua 核心。是虛擬機器偵測到運算中涉及的值有元表,而且這些元表定義了該運算的元方法。然而,由於元表是一個常規表格,任何人都可以使用它。

tostring 函式提供了一個典型的範例。正如我們先前所見,tostring 以相當簡單的格式表示表格

    print({})      --> table: 0x8062ac0
(請注意,print 始終呼叫 tostring 來格式化其輸出。) 然而,在格式化物件時,tostring 首先檢查物件是否有一個具有 __tostring 欄位的元表。如果是這樣,tostring 會呼叫對應的值(必須是函式)來執行其工作,並將物件作為引數傳遞。這個元方法傳回的任何值都是 tostring 的結果。

在我們使用集合的範例中,我們已經定義了一個函式來將集合表示為字串。因此,我們只需要在集合元表中設定 __tostring 欄位

    Set.mt.__tostring = Set.tostring
在那之後,每當我們以集合作為引數呼叫 print 時,print 會呼叫 tostring,而 tostring 會呼叫 Set.tostring
    s1 = Set.new{10, 4, 5}
    print(s1)    --> {4, 5, 10}

setmetatable/getmetatable 函式也使用元欄位,在這種情況下用於保護元表。假設您想要保護您的集合,以便使用者既無法看到也無法變更其元表。如果您在元表中設定一個 __metatable 欄位,getmetatable 會傳回此欄位的值,而 setmetatable 會引發錯誤

    Set.mt.__metatable = "not your business"
    
    s1 = Set.new{}
    print(getmetatable(s1))     --> not your business
    setmetatable(s1, {})
      stdin:1: cannot change protected metatable