モジュールに固有の軽いユーザーデータ値を使用して、メタテーブルにマーカーフィールドを常に格納できます。
static const char *green_flavor = "green";
...
void my_setflavor(lua_State *L, void *flavor) {
lua_pushlightuserdata(L,flavor);
lua_pushlstring(L,"_flavor");
lua_rawset(L,-3);
}
void my_isflavor(lua_State *L, void *flavor) {
void *p = NULL;
lua_pushlstring(L,"_flavor");
lua_rawget(L,-2);
p = lua_touserdata(L,-1);
lua_pop(L,1);
return p == flavor;
}
次にmy_setflavor(L,&green_flavor)
、スタックの一番上にあるテーブルの _flavor フィールドを設定し、スタックの一番上にあるmy_isflavor(L,&red_flavor)
テーブルの _flavor フィールドをテストするために使用できます。
このように使用すると、_flavor フィールドは、スコープ内にシンボル green_flavor を持つモジュール内のコードによって作成できる値のみを受け取ることができ、フィールドのルックアップとその値のテストには、メタテーブル自体の取得とは別に、1 つのテーブル ルックアップのみが必要でした。 . 実際にはアドレスのみが使用されるため、変数 green_flavor の値は重要ではないことに注意してください。
センティナル値として使用できるいくつかの異なるフレーバー変数を使用すると、_flavor フィールドを使用して、いくつかの関連するメタテーブルを区別できます。
とはいえ、当然の疑問は「なぜこれを行うのか」ということです。結局、メタテーブルには、適切な動作を得るために必要なすべての情報を簡単に含めることができます。データだけでなく関数も簡単に保持でき、それらの関数は Lua だけでなく C からも取得して呼び出すことができます。