この初版はLua 5.0用に執筆されました。後続のバージョンでも大部分は関連していますが、違いがいくつかあります。
第4版は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を呼び出すと、printtostringを呼び出し、tostringはさらにSet.tostringを呼び出します
    s1 = Set.new{10, 4, 5}
    print(s1)    --> {4, 5, 10}

setmetatable/getmetatable関数でもメタフィールドを使用します。この場合はメタテーブルを保護するためです。セットを保護したいとしましょう。そうすると、ユーザーはメタテーブルを見ることも変更することもできません。メタテーブルに__metatable fieldを設定すると、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