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


13.2 – 關聯元方法

元表還允許我們通過元方法 __eq相等性)、__lt小於)和 __le小於或等於)賦予關聯運算子意義。其他三個關聯運算子沒有單獨的元方法,因為 Lua 將 a ~= b 轉換為 not (a == b),將 a > b 轉換為 b < a,將 a >= b 轉換為 b <= a

(大括號:在 Lua 4.0 之前,所有順序運算子都轉換為一個運算子,方法是將 a <= b 轉換為 not (b < a)。但是,當我們有偏序時(即,當我們類型中的所有元素沒有適當地排序時),這種轉換是不正確的。例如,由於非數字NaN)的值,浮點數在大多數機器中沒有完全排序。根據目前幾乎所有硬體都採用的 IEEE 754 標準,NaN 表示未定義的值,例如 0/0 的結果。該標準規定,涉及 NaN 的任何比較都應導致 false。這意味著 NaN <= x 永遠為 false,但 x < NaN 也為 false。這意味著從 a <= bnot (b < a) 的轉換在這種情況下無效。)

在我們集合的範例中,我們遇到了類似的問題。集合中 <= 的一個顯而易見(且有用的)含義是集合包含:a <= b 表示 ab 的子集。有了這個含義,a <= bb < a 都可能是 false;因此,我們需要為 __le小於或等於)和 __lt小於)定義單獨的實作

    Set.mt.__le = function (a,b)    -- set containment
      for k in pairs(a) do
        if not b[k] then return false end
      end
      return true
    end
    
    Set.mt.__lt = function (a,b)
      return a <= b and not (b <= a)
    end
最後,我們可以通過集合包含來定義集合相等性
    Set.mt.__eq = function (a,b)
      return a <= b and b <= a
    end
在這些定義之後,我們現在準備好比較集合
    s1 = Set.new{2, 4}
    s2 = Set.new{4, 10, 2}
    print(s1 <= s2)       --> true
    print(s1 < s2)        --> true
    print(s1 >= s1)       --> true
    print(s1 > s1)        --> false
    print(s1 == s2 * s1)  --> true

與算術元方法不同,關係元方法不支援混合類型。它們對混合類型的行為模擬了 Lua 中這些運算子的常見行為。如果您嘗試比較字串和數字的順序,Lua 會引發錯誤。類似地,如果您嘗試比較兩個具有不同順序元方法的物件,Lua 會引發錯誤。

等式比較絕不會引發錯誤,但如果兩個物件具有不同的元方法,則等式運算會導致 false,甚至不會呼叫任何元方法。同樣,此行為模擬了 Lua 的常見行為,它總是將字串分類為與數字不同,而不管它們的值如何。Lua 只有在兩個被比較物件共用此元方法時才會呼叫等式元方法。