Skip to content

Alternative Table Dumper (with indentation)

Ryan Rion edited this page Apr 15, 2016 · 2 revisions

A simple table pretty-printer, using indentation. Doesn't output valid moonscript code, because string values are not put in quotes. This could easily be changed, but serialization isn't the purpose of this module.

This module adds two functions to the debug module. While it may seem a little unorthodox, this after-the-fact modification of the existing lua standard libraries is because it is common that, when a project is ready for release, one adds export debug = nil to the beginning of the project, so that any lingering debug code that is slowing your application down is caught with error messages in the final stage of testing. Generally, print statements are also removed in this same stage, to prevent pollution of the console and because stringification of objects sometimes has a significant processor overhead. Consequently, it seems natural to put the debug printing function in the debug library, so that all unwanted testing code can be removed with one line.

Implementation

ilevel = 0
indent = (a, b)->
    steps, fn = if b
        a, b
    else
        1, a
    ilevel += steps
    fn!
    ilevel -= steps
writeindent = -> io.write "   "\rep ilevel

debug.write = =>
    visited = {}
    _write = =>
        if type(self) == 'table' and not visited[self]
            if not (@@ and @@__name and not @__tostring)
                visited[self] = true
                print "{"
                for k, v in pairs self
                    indent ->
                        writeindent!
                        _write k
                        io.write ': '
                        _write v
                        print!
                writeindent!
                _write "}"
            elseif @__tostring
                io.write @__tostring!
            else
                io.write @@__name
        else
            io.write tostring self
    _write self

debug.print = (...)->
    values = {...}
    for key, value in pairs(values)
        debug.write value
        io.write ', ' if next values, key
    print!

Usage

This module introduces two functions, debug.write and debug.print, which are analogous to the built-in io.write and print functions, except that they handle tables correctly.

To prevent cycles from being printed, a simple rule is used that every table is only printed once in a given invocation of debug.print or debug.write. Even if there are no cycles, and the table structure just contains non-tree-like references, it will still print each table only once.

Every key-value pair is printed on a separate line, so, although always remaining fairly readable, the output can get rather large fairly quickly.