我有一個情況,其中兩個庫L,M正試圖爲_G設置一個metatable(分別命名爲mL,mM)。在metatables中唯一的東西是__index。鏈Lua metatables
如何鏈接這兩個metatables,以便在__index中一個失敗時調用另一箇中的索引?
我有一個情況,其中兩個庫L,M正試圖爲_G設置一個metatable(分別命名爲mL,mM)。在metatables中唯一的東西是__index。鏈Lua metatables
如何鏈接這兩個metatables,以便在__index中一個失敗時調用另一箇中的索引?
有一個元表存儲都mL
和mM
,如果一個返回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
[注意既圖書館metatables被修改,這將工作取決於最後安裝(「贏得」競爭)。]
使用__metatable給他們一個實際上不是metatable的表或給圖書館一個不同的setmetatable:這樣他們不能改變你的_G metatable。
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
(取決於庫是如何做的事情)
如果你仍然想跟蹤它的元表的東西;通過山看回之前OB(如果你確實想鏈__index查找,添加到表):
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
否則,這是非常不好的做法爲圖書館做;告訴作者不要!
-1的任何原因? –