Открыть меню
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

Модуль:Class

Материал из wiki.iccup.org

Enables equal 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 Lua and wikicode can call the same function. ==Usage== Using this module is straightforward. Here's an 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 can be called from both Lua and wikicode with the same arguments. To illustrate, you can use Cool (2, 3) in Lua, and also use {{#invoke |doCoolStuff|2|3}} in wikicode, and both will return 5. ===Named Arguments=== When named arguments are provided, there's a slight change. Named arguments are supplied as a Lua table and are always the first argument. Here's how:

 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 call Cool ({c = 5}, 2, 3) in Lua, and similarly use {{#invoke |doCoolStuff|2|3|c=5}} in wikicode, and both will return 10. ===Advanced Usage=== Module:Class supports advanced usage scenarios via the export function's options parameter. These options are passed directly to the Module:Arguments, allowing you to specify features such as frame inheritance, trimming, and more. For more details, refer to iCCup's Module documentation.

API

Программное имя: Class


export (class: table, options: table) → class

Adjusts the provided table so that its public functions (those not prefixed with an underscore) are usable from both Lua and wikicode, and returns the modified table. Note: Avoid creating underscored versions of your public methods—use distinct names. For instance, don't use both copy() and _copy() in the same module. The options parameter allows passing arguments to Module:Arguments's getArgs method.




new (base: class, init: function) → class

Creates a new class by setting the proper metadata. If a base class is provided, it will be used as the base. An optional init function can act as a constructor. If only init is provided, it functions independently.




Посмотрите всю нашу документацию iCCup здесь.



local Arguments = require('Module:Arguments')

local Class = {}

Class.PRIVATE_FUNCTION_SPECIFIER = '_'

---@class BaseClass
---@operator call:self
---@field is_a fun(self, BaseClass):boolean

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

    instance.is_a = function(self, class)
        local m = getmetatable(self)
        while m do
            if m == class then
                return true
            end
            m = m._base
        end
        return false
    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

local Table = {}

-- Duplicate Table.isNotEmpty() here to avoid circular dependencies with Table
function Table.isNotEmpty(tbl)
    -- luacheck: push ignore (Loop can be executed at most once)
    for _ in pairs(tbl) do
        return true
    end
    -- luacheck: pop
    return false
end

---
-- Wrap the given function with an argument parser so that both wikicode and lua
-- arguments are accepted
--
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 namedArgs, indexedArgs = Class._frameToArgs(frame, options)
            if namedArgs then
                return f(namedArgs, unpack(indexedArgs))
            else
                return f(unpack(indexedArgs))
            end
        else
            return f(...)
        end
    end
end

--[[
Translates a frame object into arguments expected by a lua function.
]]
function Class._frameToArgs(frame, options)
    local args = Arguments.getArgs(frame, options)

    -- getArgs adds a metatable to the table. This breaks unpack. So we remove it.
    -- We also add all named params to a special table, since unpack removes them.
    local indexedArgs = {}
    local namedArgs = {}
    for key, value in pairs(args) do
        if type(key) == 'number' then
            indexedArgs[key] = value
        else
            namedArgs[key] = value
        end
    end

    return (Table.isNotEmpty(namedArgs) and namedArgs or nil), indexedArgs
end

-- Реализация метода instanceOf
function Class.instanceOf(object, class)
    -- Проверяем, является ли объект экземпляром класса
    if type(object) == 'table' and object.__index == class then
        return true
    end
    -- Проверяем для наследуемых классов
    local super = object._base
    while super do
        if super == class then
            return true
        end
        super = super._base
    end
    return false
end

return Class
Содержание