Jackmcbarn has uploaded a new change for review. https://gerrit.wikimedia.org/r/178760
Change subject: Allow non-hacky modification of loadData tables ...................................................................... Allow non-hacky modification of loadData tables It's always been possible to use rawset() to modify loadData tables. This adds a non-hacky way to do so. With this method, iteration works normally, and there's still no cross-invoke leakage. Change-Id: Ic647be3e00b9c80a54cecff2c87b072b84c36e59 --- M engines/LuaCommon/lualib/mw.lua M tests/engines/LuaCommon/CommonTests.lua 2 files changed, 20 insertions(+), 35 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Scribunto refs/changes/60/178760/1 diff --git a/engines/LuaCommon/lualib/mw.lua b/engines/LuaCommon/lualib/mw.lua index f6a2aee..9e8a9d7 100644 --- a/engines/LuaCommon/lualib/mw.lua +++ b/engines/LuaCommon/lualib/mw.lua @@ -628,18 +628,18 @@ end --- --- Wrapper for mw.loadData. This creates the read-only dummy table for +-- Wrapper for mw.loadData. This creates the dummy table for -- accessing the real data. -- -- @param data table Data to access -- @param seen table|nil Table of already-seen tables. -- @return table local function dataWrapper( data, seen ) - local t = {} + local t, dummyValue, changes = {}, {} seen = seen or { [data] = t } local function pairsfunc( s, k ) - k = next( data, k ) + k = next( changes or data, k ) if k ~= nil then return k, t[k] end @@ -648,7 +648,7 @@ local function ipairsfunc( s, i ) i = i + 1 - if data[i] ~= nil then + if t[i] ~= nil then return i, t[i] end return -- no nil to match default ipairs() @@ -657,6 +657,9 @@ local mt = { __index = function ( tt, k ) assert( t == tt ) + if changes and changes[k] ~= dummyValue then + return changes[k] + end local v = data[k] if type( v ) == 'table' then seen[v] = seen[v] or dataWrapper( v, seen ) @@ -664,8 +667,15 @@ end return v end, - __newindex = function ( t, k, v ) - error( "table from mw.loadData is read-only", 2 ) + __newindex = function ( tt, k, v ) + assert( t == tt ) + if not changes then + changes = {} + for k in pairs( data ) do + changes[k] = dummyValue + end + end + changes[k] = v end, __pairs = function ( tt ) assert( t == tt ) diff --git a/tests/engines/LuaCommon/CommonTests.lua b/tests/engines/LuaCommon/CommonTests.lua index fef18ed..acb9a80 100644 --- a/tests/engines/LuaCommon/CommonTests.lua +++ b/tests/engines/LuaCommon/CommonTests.lua @@ -177,17 +177,6 @@ return d end -function test.loadData.set( v, ... ) - local d = mw.loadData( 'Module:CommonTests-data' ) - local n = select( '#', ... ) - for i = 1, n - 1 do - local k = select( i, ... ) - d = d[k] - end - d[select( n, ... )] = v - return d[select( n, ... )] -end - function test.loadData.recursion() local d = mw.loadData( 'Module:CommonTests-data' ) return d == d.t, d.t == d.t.t, d.table2 == d.table @@ -208,12 +197,10 @@ return 'setmetatable succeeded' end -function test.loadData.rawset() - -- We can't easily prevent rawset (and it's not worth trying to redefine - -- it), but we can make sure it doesn't affect other instances of the data +function test.loadData.set() local d1 = mw.loadData( 'Module:CommonTests-data' ) local d2 = mw.loadData( 'Module:CommonTests-data' ) - rawset( d1, 'str', 'ugh' ) + d1.str = 'ugh' local d3 = mw.loadData( 'Module:CommonTests-data' ) return d1.str, d2.str, d3.str end @@ -368,20 +355,8 @@ func = test.loadData.setmetatable, expect = "cannot change a protected metatable" }, - { name = 'mw.loadData, setter (1)', - func = test.loadData.set, args = { 'ugh', 'str' }, - expect = "table from mw.loadData is read-only", - }, - { name = 'mw.loadData, setter (2)', - func = test.loadData.set, args = { 'ugh', 'table', 2 }, - expect = "table from mw.loadData is read-only", - }, - { name = 'mw.loadData, setter (3)', - func = test.loadData.set, args = { 'ugh', 't' }, - expect = "table from mw.loadData is read-only", - }, - { name = 'mw.loadData, rawset', - func = test.loadData.rawset, + { name = 'mw.loadData, set', + func = test.loadData.set, expect = { 'ugh', 'foo bar', 'foo bar' }, }, } ) -- To view, visit https://gerrit.wikimedia.org/r/178760 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic647be3e00b9c80a54cecff2c87b072b84c36e59 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Scribunto Gerrit-Branch: master Gerrit-Owner: Jackmcbarn <jackmcb...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits