Module:Class
Enables equals treatment of LUA and wikicode users for modules. Using this module means you will no longer need to have two different entry points for each function, both wikicode and LUA can call the same function.
Usage[edit]
Usage of this module is simple. See the following example:
local Class = require('Module:Class') <!--- Add the import local Cool = Class.new() <!--- Create a class function Cool.doCoolStuff(a, b) <!--- Note the colon symbol! return a + b end return Cool.export() <!--- Export the table
Now, doCoolStuff
will be callable from both LUA and wikicode with the same arguments.
To repeat, you can now do Cool:doCoolStuff(2, 3)
while also being able to do {{#invoke:Lua|invoke|module=SomeModule|fn=doCoolStuff|2|3}}
and both will return 5.
Named arguments[edit]
When named arguments are provided, things change slightly. Named arguments are provided as a lua table, and are always the first argument. So, example:
local Class = require('Module:Class') <!--- Add the import local Cool = Class.new() <!--- Create a class function Cool.doCoolStuff(args, a, b) <!--- Named args are now the first argument! return a + b + args.c end return Cool.export() <!--- Export the table
You can now do Cool:doCoolStuff(2, 3, {c = 5})
while also being able to do {{#invoke:Lua|invoke|module=SomeModule|fn=doCoolStuff|2|3|c=5}}
and both will return 10.
Advanced[edit]
Module:Class supports advanced usage scenarios via export
's options parameter. These options are passed straight to Module:Arguments, which allows you to specify such things as frame inheritance, trimming functionality, and more. For details on this, see Wikipedia's documentation.
API[edit]
- Programmatic name: Class
- export(class: table, options: table) → class
Adjusts the table given so that its public functions (the ones not prefixed using an underscore) are usable from both LUA and wikicode and returns the adjusted table. Note: you can not create underscored versions of your public versions, please use a different name instead (with underscore if desired). So no copy() and _copy() in the same Module. The options arguments allows for providing arguments to Module:Arguments's getArgs.
- new(base: class, init: function) → class
Creates a new class, by setting the proper metadata. If base is given, that will be used as base class. When init is supplied with a function, it can be used as a constructor. If only init is given, the function will still work.
See all our documentation here.
The above documentation is transcluded from Module:Class/doc. (edit | history) Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages. Subpages of this module. |
--- -- @Liquipedia -- wiki=commons -- page=Module:Class -- -- Please see https://github.com/Liquipedia/Lua-Modules to contribute -- local Arguments = require('Module:Arguments') local Class = {} Class.PRIVATE_FUNCTION_SPECIFIER = '_' ---@class BaseClass ---@operator call:self ---@field init fun(self, ...) function Class.new(base, init) local instance = {} if not init and type(base) == 'function' then init = base base = nil elseif type(base) == 'table' then for index, value in pairs(base) do instance[index] = value end instance._base = base end instance.__index = instance local metatable = {} metatable.__call = function(class_tbl, ...) local object = {} setmetatable(object, instance) instance.init(object, ...) return object end instance.init = function(object, ...) if base then base.init(object, ...) end if init then init(object, ...) end end instance.export = function(options) return Class.export(instance, options) end setmetatable(instance, metatable) return instance end ---@generic T:table ---@param class T ---@param options ?table ---@return T function Class.export(class, options) for name, f in pairs(class) do -- We only want to export functions, and only functions which are public (no underscore) if ( type(f) == 'function' and (not string.find(name, Class.PRIVATE_FUNCTION_SPECIFIER)) ) then class[name] = Class._wrapFunction(class[name], options) end end return class end --- -- Wrap the given function with an argument parses so that both wikicode and lua -- arguments are accepted -- ---@generic F:fun(props: table) ---@param f F ---@param options table? ---@return F function Class._wrapFunction(f, options) options = options or {} local alwaysRewriteArgs = options.trim or options.removeBlanks or options.valueFunc ~= nil return function(...) -- We cannot call getArgs with a spread operator when these are just lua -- args, so we need to wrap it local input = {...} local frame = input[1] local shouldRewriteArgs = alwaysRewriteArgs or ( #input == 1 and type(frame) == 'table' and type(frame.args) == 'table' ) if shouldRewriteArgs then local args = Arguments.getArgs(frame, options) return f(args) else return f(...) end end end ---@param instance any ---@param class BaseClass ---@return boolean function Class.instanceOf(instance, class) local metatable = getmetatable(instance) while metatable do if metatable == class then return true end metatable = metatable._base end return false end return Class