diff --git a/luprex/core/cpp/world-difftab.cpp b/luprex/core/cpp/world-difftab.cpp index 08b217e2..48d4dfb6 100644 --- a/luprex/core/cpp/world-difftab.cpp +++ b/luprex/core/cpp/world-difftab.cpp @@ -290,7 +290,11 @@ static void patch_table(LuaStack &LS0, LuaSlot tangibles, LuaSlot ntmap, LuaSlot for (int i = 0; i < ndiffs; i++) { set_transmitted_value(LS, tangibles, ntmap, key, sb); set_transmitted_value(LS, tangibles, ntmap, val, sb); - LS.rawset(tab, key, val); + if (LS.isnil(key)) { + LS.setmetatable(tab, val); + } else { + LS.rawset(tab, key, val); + } } LS.result(); } diff --git a/luprex/core/lua/ut-tablecmp.lua b/luprex/core/lua/ut-tablecmp.lua index c2136e4f..ce596227 100644 --- a/luprex/core/lua/ut-tablecmp.lua +++ b/luprex/core/lua/ut-tablecmp.lua @@ -8,6 +8,7 @@ local tdc = table.diffcompare local tda = table.diffapply function unittests.diffcompare() + local mtab = nil local rtab = nil -- No differences in these simple-valued tables. @@ -73,6 +74,15 @@ function unittests.diffcompare() assert(tdc(mtnmap, {a={}}, stnmap, {}) == "") assert(tdc(mtnmap, {a={}}, stnmap, {a=3}) == "a=nil;") + -- transmit a correction to the metatable. + mtab={} + stab={} + setmetatable(mtab, mtab10) + setmetatable(stab, stab10) + assert(tdc(mtnmap, mtab, stnmap, {}) == "nil=table 10;") + assert(tdc(mtnmap, mtab, stnmap, stab) == "") + assert(tdc(mtnmap, {}, stnmap, stab) == "nil=nil;") + -- we're not going to test tangibles -- creating tangibles here is too difficult. end @@ -83,6 +93,8 @@ function unittests.diffapply() local tnmap={} tnmap[tab10] = 10 tnmap[tab11] = 11 + local mtab=nil + local stab=nil -- verify some simple values. assert(tda(tnmap, {a=1}, {})) @@ -114,6 +126,20 @@ function unittests.diffapply() assert(not tda({}, {a={}}, rtab)) assert(rtab.a == nil) + -- transmit a correction to the metatable + mtab={} + rtab={} + setmetatable(mtab, tab10) + assert(tda(tnmap, mtab, rtab)) + assert(getmetatable(rtab) == tab10) + + -- transmit a clearing of the metatable + mtab={} + rtab={} + setmetatable(rtab, tab10) + assert(tda(tnmap, mtab, rtab)) + assert(getmetatable(rtab) == nil) + -- don't test tangibles. end