この初版は Lua 5.0 用に書かれたものです。その後のバージョンでも依然として関連していますが、いくつか違いがあります。
第 4 版は Lua 5.3 を対象としており、Amazon やその他の書店で購入できます。
本を購入することで、Lua プロジェクトをサポートすることもできます。


13.2 – 関係メタメソッド

メタテーブルでは、__eq (等式)、__lt (未満)、および __le (以下) のメタメソッドによって、関係演算子に意味を持たせることができます。他の 3 つの関係演算子には別のメタメソッドはありません。Lua は a ~= bnot (a == b)a > bb < a、および a >= bb <= a に変換します。

(大カッコ: Lua 4.0 まで、すべての順序演算子は 1 つに翻訳され、a <= bnot (b < a) に翻訳していました。ただし、部分順序の場合、つまりタイプ内のすべての要素が適切に順序付けられていない場合、この変換は正しくありません。たとえば、ほとんどのマシンでは浮動小数点数は完全に順序付けされていません。これは Not a Number (NaN) の値が理由です。現在ほとんどすべてのハードウェアで採用されている IEEE 754 規格によると、NaN は 0/0 の結果などの未定義値を表します。この規格では、NaN が含まれる比較はすべて false になる必要があると規定されています。つまり、NaN <= x は常に false ですが、x < NaN もまた false です。これは a <= b から not (b < a) への変換が、このケースでは有効ではないことを意味します。)

セットを使用した例では、同様の問題が発生します。セットにおける <= の分かりやすい (かつ役立つ) 意味は、セットの包含です: a <= bab のサブセットであることを意味します。この意味では、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 はエラーを発生させます。同様に、順序に異なるメタメソッドを持つ 2 つのオブジェクトを比較しようとすると、Lua はエラーを発生させます。

等式比較はエラーを発生することはありませんが、2 つのオブジェクトに異なるメタメソッドがある場合、等価演算はメタメソッドを呼び出さずに false になります。繰り返しますが、この動作は Lua の一般的な動作を模倣するものであり、Lua は値に関係なく常に文字列を数値とは異なるものとして分類します。Lua は、比較される 2 つのオブジェクトがこのメタメソッドを共有する場合にのみ等価メタメソッドを呼び出します。