2011-11-13 14 views
4

私は2つのライブラリL、Mが_G(それぞれmL、mMという名前)のメタテーブルを設定しようとしている状況があります。メタテーブル内の唯一のものは__indexです。チェーンLuaのメタデータ

これらの2つのメタデータを連鎖することで、1つの__indexが失敗した場合、他のインデックスを呼び出すことができますか?

答えて

2

mLmMの両方を保存する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) 
+0

-1の理由は何ですか? –

1

は、あなたのコードはライブラリの後、_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 

をライブラリのメタデータが変更されると、最後にインストールされたもの(競争に勝ったもの)が動作します。]

1

__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検索したい場合)作者には言わないでください!