Usage
This module provides a function which adds fallback functionalities to a given table args according to the fallback sequence given in arg_aliases. Note that this module currently only supports indexing, i.e. __index
.
Parameters
- args
- The table to add fallback functionalities.
- arg_aliases
- A table of the form
{ [key] = { fallback1, fallback2... } }
.
Example
The following snippet adds template parameter aliases to a metatable obtained from Module:Arguments.
local getArgs = require('Module:Arguments').getArgs
local makeFallback = require('Module:Sandbox/Artoria2e5/Fallback')
local p = {}
function p.main(frame)
local args = makeFallback(getArgs(frame), {
["foo_bar"] = {"foobar", "foo", "bar"}
})
-- Try calling this template with |foo=42.
return (args["foo_bar"] or "nothing here!")
end
return p
The following snippet shows basic usage of indexing fallback.
local makeFallback = require('Module:Arguments/Fallback')
table = {
["bar"] = "crunchy"
}
makeFallback(table, {
["foo_bar"] = {"foobar", "foo", "bar"}
})
return table["foo_bar"]
The following snippet creates a fallback list with all fallback names aliasing back to the main name.
local makeFallback = require('Module:Sandbox/Artoria2e5/Fallback')
table = {
["bar"] = "crunchy"
}
makeFallback(table, {
["foo_bar"] = {"foobar", "foo", "bar"},
["foo"] = {"foo_bar"},
["foobar"] = {"foo_bar"},
["bar"] = {"foo_bar"}
})
return table["foo"]
-- 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