<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.geministation.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ALogger</id>
	<title>Module:Logger - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.geministation.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ALogger"/>
	<link rel="alternate" type="text/html" href="https://wiki.geministation.com/index.php?title=Module:Logger&amp;action=history"/>
	<updated>2026-06-04T11:45:23Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.geministation.com/index.php?title=Module:Logger&amp;diff=8878&amp;oldid=prev</id>
		<title>Banri: Created page with &quot;-- &lt;nowiki&gt; local p = {}  function p.log(obj) 	if type(obj) ~= &#039;table&#039; then 		mw.log(&#039;Argument is a &#039;..type(obj)..&#039;, not a table&#039;) 		return 	end 	for i,v in pairs(obj) do 		mw...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.geministation.com/index.php?title=Module:Logger&amp;diff=8878&amp;oldid=prev"/>
		<updated>2021-03-24T01:57:33Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- &amp;lt;nowiki&amp;gt; local p = {}  function p.log(obj) 	if type(obj) ~= &amp;#039;table&amp;#039; then 		mw.log(&amp;#039;Argument is a &amp;#039;..type(obj)..&amp;#039;, not a table&amp;#039;) 		return 	end 	for i,v in pairs(obj) do 		mw...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;nowiki&amp;gt;&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.log(obj)&lt;br /&gt;
	if type(obj) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		mw.log(&amp;#039;Argument is a &amp;#039;..type(obj)..&amp;#039;, not a table&amp;#039;)&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	for i,v in pairs(obj) do&lt;br /&gt;
		mw.log(tostring(i)..&amp;#039;\t&amp;#039;..tostring(v))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function deep_log(obj, prefix)&lt;br /&gt;
	local pfix = &amp;#039;&amp;#039;&lt;br /&gt;
	if prefix then&lt;br /&gt;
		pfix = prefix..&amp;#039;.&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i,v in pairs(obj) do&lt;br /&gt;
		mw.log(string.format(&amp;#039;%s%s\t%s&amp;#039;,pfix,tostring(i),tostring(v)))&lt;br /&gt;
		if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			deep_log(v,pfix..tostring(i))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.deep_log(obj)&lt;br /&gt;
	if type(obj) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		mw.log(&amp;#039;Argument is a &amp;#039;..type(obj)..&amp;#039;, not a table&amp;#039;)&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	deep_log(obj, nil)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function default( input, defaults )&lt;br /&gt;
    input = input or {}&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    for k, v in pairs( input ) do&lt;br /&gt;
        res[k] = v&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for k, v in pairs( defaults ) do&lt;br /&gt;
        if res[k] == nil then&lt;br /&gt;
            res[k] = v&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return res&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isCleanName( str )&lt;br /&gt;
    return not (string.find( str, &amp;#039;^%d&amp;#039; ) or string.find( str, &amp;#039;[^_%w]&amp;#039; ))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.dumpObject( object, options )&lt;br /&gt;
    options = default( options, {&lt;br /&gt;
        clean = false,&lt;br /&gt;
        indentSize = 2,&lt;br /&gt;
        tabSize = 4,&lt;br /&gt;
        collapseLimit = 0,&lt;br /&gt;
        collapseArrays = true,&lt;br /&gt;
        wrapLongArrays = false,&lt;br /&gt;
        collapseObjects = true,&lt;br /&gt;
        useTabs = false,&lt;br /&gt;
        addEqualSignSpaces = false,&lt;br /&gt;
        addBracketSpaces = true,&lt;br /&gt;
        numberPrecision = -1&lt;br /&gt;
    } )&lt;br /&gt;
    local indentChar = options.useTabs and &amp;#039;\t&amp;#039; or &amp;#039; &amp;#039;&lt;br /&gt;
    local doneTable = {}&lt;br /&gt;
    local doneObj = {}&lt;br /&gt;
    local ct = {}&lt;br /&gt;
&lt;br /&gt;
    local function sorter( a, b )&lt;br /&gt;
        local ta, tb = type( a ), type( b )&lt;br /&gt;
        if ta ~= tb then&lt;br /&gt;
            return ta &amp;lt; tb&lt;br /&gt;
        end&lt;br /&gt;
        if ta == &amp;#039;string&amp;#039; or ta == &amp;#039;number&amp;#039; then&lt;br /&gt;
            return a &amp;lt; b&lt;br /&gt;
        end&lt;br /&gt;
        if ta == &amp;#039;boolean&amp;#039; then&lt;br /&gt;
            return tostring( a ) &amp;lt; tostring( b )&lt;br /&gt;
        end&lt;br /&gt;
        return false -- Incomparable&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function _dumpObject( object, indent, expandTable )&lt;br /&gt;
        local tp = type( object )&lt;br /&gt;
        if tp == &amp;#039;nil&amp;#039; or tp == &amp;#039;boolean&amp;#039; then&lt;br /&gt;
            return tostring( object )&lt;br /&gt;
        elseif tp == &amp;#039;number&amp;#039; then&lt;br /&gt;
            if options.numberPrecision &amp;lt; 0 then&lt;br /&gt;
                return tostring( object )&lt;br /&gt;
            else&lt;br /&gt;
                return (string.format(&amp;#039;%.&amp;#039; .. options.numberPrecision .. &amp;#039;f&amp;#039;, object):gsub( &amp;#039;%.?0*$&amp;#039;, &amp;#039;&amp;#039; ))&lt;br /&gt;
            end&lt;br /&gt;
        elseif tp == &amp;#039;string&amp;#039; then&lt;br /&gt;
            return string.format( &amp;quot;%q&amp;quot;, object )&lt;br /&gt;
        elseif tp == &amp;#039;table&amp;#039; then&lt;br /&gt;
            if not doneObj[object] then&lt;br /&gt;
                local s = tostring( object )&lt;br /&gt;
                if string.find(s, &amp;#039;^table$&amp;#039;) then&lt;br /&gt;
                    ct[tp] = ( ct[tp] or 0 ) + 1&lt;br /&gt;
                    doneObj[object] = &amp;#039;table#&amp;#039; .. ct[tp]&lt;br /&gt;
                else&lt;br /&gt;
                    doneObj[object] = s&lt;br /&gt;
                    doneTable[object] = true&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if (doneTable[object] or not expandTable) and not options.clean then&lt;br /&gt;
                return doneObj[object]&lt;br /&gt;
            end&lt;br /&gt;
            doneTable[object] = true&lt;br /&gt;
&lt;br /&gt;
            local colLen = options.useTabs and (options.tabSize * indent) or indent -- Collapsed string length&lt;br /&gt;
            local indentIndexes = {}&lt;br /&gt;
            local newLineIndexes = {}&lt;br /&gt;
            local equalSignIndexes = {}&lt;br /&gt;
            local arrayPartEndIndex = 1&lt;br /&gt;
            local ret = options.clean and { &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, &amp;#039;{\n&amp;#039; } or { (doneObj[object] .. &amp;#039; (#=&amp;#039; .. #object), &amp;#039;&amp;#039;, &amp;#039; {\n&amp;#039; }&lt;br /&gt;
            colLen = colLen + #ret[1]&lt;br /&gt;
&lt;br /&gt;
            local function addIndent()&lt;br /&gt;
                ret[#ret + 1] = string.rep( indentChar, indent + options.indentSize )&lt;br /&gt;
                indentIndexes[#indentIndexes + 1] = #ret&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            local function addNewline()&lt;br /&gt;
                ret[#ret + 1] = &amp;quot;,\n&amp;quot;&lt;br /&gt;
                newLineIndexes[#newLineIndexes + 1] = #ret&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            local function addEqualSign()&lt;br /&gt;
                ret[#ret + 1] = &amp;quot; = &amp;quot;&lt;br /&gt;
                equalSignIndexes[#equalSignIndexes + 1] = #ret&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            local mt = getmetatable( object )&lt;br /&gt;
            if mt and not options.clean then&lt;br /&gt;
                addIndent()&lt;br /&gt;
                ret[#ret + 1] = &amp;#039;metatable = &amp;#039;&lt;br /&gt;
                colLen = colLen + #ret[#ret]&lt;br /&gt;
                ret[#ret + 1] = _dumpObject( mt, indent + options.indentSize, false )&lt;br /&gt;
                colLen = colLen + #ret[#ret]&lt;br /&gt;
                addNewline()&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            local doneKeys = {}&lt;br /&gt;
            local count = 0&lt;br /&gt;
&lt;br /&gt;
            for key, value in ipairs( object ) do&lt;br /&gt;
                doneKeys[key] = true&lt;br /&gt;
                addIndent()&lt;br /&gt;
                ret[#ret + 1] = _dumpObject( value, indent + options.indentSize, true )&lt;br /&gt;
                colLen = colLen + #ret[#ret]&lt;br /&gt;
                addNewline()&lt;br /&gt;
&lt;br /&gt;
                count = count + 1&lt;br /&gt;
            end&lt;br /&gt;
            arrayPartEndIndex = #ret&lt;br /&gt;
&lt;br /&gt;
            local keys = {}&lt;br /&gt;
            for key in pairs( object ) do&lt;br /&gt;
                if not doneKeys[key] then&lt;br /&gt;
                    keys[#keys + 1] = key&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            table.sort( keys, sorter )&lt;br /&gt;
            if not options.clean then ret[2] = &amp;#039;, n=&amp;#039; .. count .. &amp;#039;)&amp;#039; end&lt;br /&gt;
            colLen = colLen + #ret[2]&lt;br /&gt;
&lt;br /&gt;
            for i = 1, #keys do&lt;br /&gt;
                local key = keys[i]&lt;br /&gt;
                addIndent()&lt;br /&gt;
&lt;br /&gt;
                if options.clean and type( key ) == &amp;#039;string&amp;#039; and isCleanName( key ) then&lt;br /&gt;
                    ret[#ret + 1] = key&lt;br /&gt;
                    colLen = colLen + #ret[#ret]&lt;br /&gt;
                    addEqualSign()&lt;br /&gt;
                else&lt;br /&gt;
                    ret[#ret + 1] = &amp;#039;[&amp;#039;&lt;br /&gt;
                    ret[#ret + 1] = _dumpObject( key, nil, false )&lt;br /&gt;
                    colLen = colLen + #ret[#ret] + 2 -- +2 for the brackets []&lt;br /&gt;
                    ret[#ret + 1] = &amp;#039;]&amp;#039;&lt;br /&gt;
                    addEqualSign()&lt;br /&gt;
                end&lt;br /&gt;
&lt;br /&gt;
                ret[#ret + 1] = _dumpObject( object[key], indent + options.indentSize, true )&lt;br /&gt;
                colLen = colLen + #ret[#ret] + 1&lt;br /&gt;
                addNewline()&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            ret[#ret + 1] = string.rep( indentChar, indent )&lt;br /&gt;
            indentIndexes[#indentIndexes + 1] = #ret&lt;br /&gt;
            ret[#ret + 1] = &amp;#039;}&amp;#039;&lt;br /&gt;
&lt;br /&gt;
            colLen = colLen + 2 * (#newLineIndexes - 1) + (options.addBracketSpaces and 4 or 2)&lt;br /&gt;
&lt;br /&gt;
            if&lt;br /&gt;
                (options.collapseArrays or options.collapseObjects) and&lt;br /&gt;
                colLen &amp;lt;= options.collapseLimit and&lt;br /&gt;
                not (options.collapseObjects == false and count &amp;gt; #object) and&lt;br /&gt;
                not (options.collapseArrays == false and #object &amp;gt; 0)&lt;br /&gt;
            then&lt;br /&gt;
                for _, i in ipairs( indentIndexes ) do&lt;br /&gt;
                    ret[i] = &amp;#039;&amp;#039;&lt;br /&gt;
                end&lt;br /&gt;
                for _, i in ipairs( newLineIndexes ) do&lt;br /&gt;
                    ret[i] = &amp;#039;, &amp;#039;&lt;br /&gt;
                end&lt;br /&gt;
                if not options.addEqualSignSpaces then&lt;br /&gt;
                    for _, i in ipairs( equalSignIndexes ) do&lt;br /&gt;
                        ret[i] = &amp;#039;=&amp;#039;&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
&lt;br /&gt;
                ret[#ret - 1] = &amp;#039;&amp;#039; -- Indentation before closing bracket&lt;br /&gt;
                ret[3] = (options.addBracketSpaces and count &amp;gt; 0) and &amp;#039;{ &amp;#039; or &amp;#039;{&amp;#039;&lt;br /&gt;
                if count &amp;gt; 0 then&lt;br /&gt;
                    if options.addBracketSpaces then ret[#ret] = &amp;#039; }&amp;#039; end&lt;br /&gt;
                    ret[#ret - 2] = &amp;#039;&amp;#039; -- Last &amp;#039;, &amp;#039;&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            if colLen &amp;gt; options.collapseLimit and options.collapseArrays and options.wrapLongArrays then&lt;br /&gt;
                local totalLen = options.collapseLimit -- Begin with collapse limit so that the first element keeps its indentation&lt;br /&gt;
                for _, i in ipairs( newLineIndexes ) do&lt;br /&gt;
                    local itemLen = #ret[i - 1] + 2 -- +2 for the &amp;#039;, &amp;#039;&lt;br /&gt;
                    if totalLen + itemLen - 1 &amp;gt;= options.collapseLimit then -- -1 to not count the space after the last ,&lt;br /&gt;
                        totalLen = indent + options.indentSize + itemLen&lt;br /&gt;
                    else&lt;br /&gt;
                        totalLen = totalLen + itemLen&lt;br /&gt;
                        ret[i - 2] = &amp;#039;&amp;#039; -- indentation&lt;br /&gt;
                        ret[i - 3] = &amp;#039;, &amp;#039;&lt;br /&gt;
                    end&lt;br /&gt;
&lt;br /&gt;
                    if i &amp;gt;= arrayPartEndIndex then&lt;br /&gt;
                        break&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            return table.concat( ret )&lt;br /&gt;
        else&lt;br /&gt;
            if not doneObj[object] then&lt;br /&gt;
                ct[tp] = ( ct[tp] or 0 ) + 1&lt;br /&gt;
                doneObj[object] = tostring( object ) .. &amp;#039;#&amp;#039; .. ct[tp]&lt;br /&gt;
            end&lt;br /&gt;
            return doneObj[object]&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return _dumpObject( object, 0, true )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.logCleanTable( object, options )&lt;br /&gt;
    mw.log( p.dumpObject( object, default( options, {&lt;br /&gt;
        clean = true,&lt;br /&gt;
        indentSize = 4,&lt;br /&gt;
        collapseLimit = 100,&lt;br /&gt;
        collapseArrays = true,&lt;br /&gt;
        collapseObjects = true,&lt;br /&gt;
        addEqualSignSpaces = false,&lt;br /&gt;
    } ) ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.logObject( object, options )&lt;br /&gt;
    mw.log( p.dumpObject( object, options ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;br /&gt;
-- &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Banri</name></author>
	</entry>
</feed>