Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/Artoria2e5/Fallback
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- A simple index fallback implementation for tables. -- Useful for template argument aliasing. -- Hmm, what about __newindex? local function makeFallback(args, arg_aliases) local oldArgsMeta = getmetatable(args) or {} local newArgsMeta = {} -- Forget about thread-safety. -- States kept to avoid strange loops. local referencedKeys = {} -- dataType:Set/hashtable-impl local attemptDepth = 0 -- useful for "last nil" case -- Start the new metatable as a copy of the old metatable. for k, v in ipairs(oldArgsMeta) do newArgsMeta[k] = v end -- Change the __index metamethod to our implementation. -- See https://www.lua.org/pil/13.4.1.html. newArgsMeta.__index = function (t, k) -- My friend, why are you here again? if referencedKeys[k] then -- You have to be drunk. Go home. return nil end referencedKeys[k] = true -- Try the old metamethod first. -- Thanks to closures, this whole oldArgsMeta object will stay. if oldArgsMeta.__index ~= nil then local val = oldArgsMeta.__index(t, k) if val ~= nil then referencedKeys = {} return val end end attemptDepth = attemptDepth + 1 -- Now try use the aliases given. for _, v in ipairs(arg_aliases[k] or {}) do -- If a working value is found, use it. -- Note: mw-argument-specific empty str chk. if t[v] ~= nil and t[v] ~= '' then referencedKeys = {} return t[v] end end attemptDepth = attemptDepth - 1 if attemptDepth == 0 then referencedKeys = {} end return nil end setmetatable(args, newArgsMeta) return args -- just in case someone wants a return value. end return makeFallback --[[ P.S. Don't blame me for writing these obj-states. Sure, we can use an accumulator and do some "index with acc" ourselves, but that sounds like too much work done just to avoid states. Here is that custom index function in case anyone is curious about it: function index_w_acc(t, k, acc) local v = rawget(t, k) if v ~= nil return v else return getmetatable(t).__index(k, acc) end end My guess is that it will certainly be slower than the native t[k] one. Perhaps not getting the metatable every time will help a bit. ]]--
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
Template:Module other
(
edit
)
Template:Module rating
(
edit
)
Template:Ombox
(
edit
)
Module:Arguments
(
edit
)
Module:Message box
(
edit
)
Module:Message box/configuration
(
edit
)
Module:Message box/ombox.css
(
edit
)
Module:Sandbox/Artoria2e5/Fallback/doc
(
edit
)
Module:Yesno
(
edit
)