私は2つのライブラリL、Mが_G(それぞれmL、mMという名前)のメタテーブルを設定しようとしている状況があります。メタテーブル内の唯一のものは__indexです。チェーンLuaのメタデータ
これらの2つのメタデータを連鎖することで、1つの__indexが失敗した場合、他のインデックスを呼び出すことができますか?
私は2つのライブラリL、Mが_G(それぞれmL、mMという名前)のメタテーブルを設定しようとしている状況があります。メタテーブル内の唯一のものは__indexです。チェーンLuaのメタデータ
これらの2つのメタデータを連鎖することで、1つの__indexが失敗した場合、他のインデックスを呼び出すことができますか?
はmL
とmM
の両方を保存する1つのメタテーブルを持って、もう1つはnil
を返した場合、他のことを確認してください。
local metatbl = {}
metatbl.tbls = {mL, mM};
function metatbl.__index(intbl, key)
for i, mtbl in ipairs(metatbl.tbls) do
local mmethod = mtbl.__index
if(type(mmethod) == "function") then
local ret = mmethod(table, key)
if ret then return ret end
else
if mmethod[key] then return mmethod[key] end
end
return nil
end
end
setmetatable(_G,metatbl)
は、あなたのコードはライブラリの後、_G
のメタテーブル自体をいじることができポイントがありますと仮定すると、何L解決するために、約マックしているとMは、あなたは自分自身のメタテーブルに固執することができなかったことがない組み合わせ検索、例えば:しないという利点がある
combined_metatable = {
__index = function (t, k)
return mL.__index (t, k) or mM.__index (t, k)
end
}
setmetatable (_G, combined_metatable)
mL
またはmM
自体で手をつけてください。
あなたは事後に物事を修正する機会を持っていない場合は、あなただけの組み合わせ検索を行うために、ライブラリのメタテーブルの__index
エントリを変更できます。両方としてことに注意してください[
local original_mM_index = mM.__index
local original_mL_index = mL.__index
local function L_then_M_index (t, k)
return original_mL_index (t, k) or original_mM_index (t, k)
end
mL.__index = L_then_M_index
mM.__index = L_then_M_index
をライブラリのメタデータが変更されると、最後にインストールされたもの(競争に勝ったもの)が動作します。]
__metatableを使用して、実際にメタテーブルではないテーブルを与えるか、ライブラリに異なる設定可能:あなたの_Gメタテーブルを変更することはできません。 (ライブラリが物事をどうするかに依存する)
getmetatable(getfenv()).__metatable = function (o) return { } end
OR
local orig_setmetatable = setmetatable
function setmetatable (ob , mt)
if ob == getfenv() or ob == _G then
return ob
else
return orig_setmetatable(ob,mt)
end
end
あなたはまだメタテーブルにそれがないものを追跡する場合。
local env_indexes = {}
setmetatable(_G,{__index=function(t,k) for i,m in ipairs(env_indexes) do local v=m[k]; if v then return v end end return nil end })
local orig_setmetatable = setmetatable
function setmetatable (ob , mt)
if ob == _G then
table.insert (env_indexes , mt.__index)
return ob
else
return orig_setmetatable(ob,mt)
end
end
そうでなければ、これはやってするライブラリーのための非常に悪い習慣です;:;戻りOBの前にMTに目を通す(テーブルに追加し、あなたが実際にチェーン__index検索したい場合)作者には言わないでください!
-1の理由は何ですか? –