diff --git a/inspect.lua b/inspect.lua index fdaf012..1476b19 100644 --- a/inspect.lua +++ b/inspect.lua @@ -143,12 +143,32 @@ local function makePath(path, key) return newPath end +local processRecursive = function(object, path, process) + local processed = process(object, path) + if type(processed) == 'table' then + local processed2 = {} + + for k,v in pairs(processed) do + processed2[k] = process(v, makePath(path, k), process) + end + + local mt = process(getmetatable(processed), makePath(path, '')) + setmetatable(processed2, mt) + processed = processed2 + end + return processed +end + ------------------------------------------------------------------- -function inspect.inspect(rootObject, options) +function inspect.inspect(root, options) options = options or {} local depth = options.depth or math.huge + local process = options.process + if process then + root = processRecursive(root, {}, process) + end - local tableAppearances = countTableAppearances(rootObject) + local tableAppearances = countTableAppearances(root) local buffer = {} local maxIds = setmetatable({}, maxIdsMetaTable) @@ -203,7 +223,7 @@ function inspect.inspect(rootObject, options) puts("]") end - local function putTable(t, path) + local function putTable(t) if alreadyVisited(t) then puts('') elseif level >= depth then @@ -227,7 +247,7 @@ function inspect.inspect(rootObject, options) for i=1, length do needsComma = commaControl(needsComma) puts(' ') - putValue(t[i], makePath(path, i)) + putValue(t[i]) end for _,k in ipairs(dictKeys) do @@ -235,14 +255,14 @@ function inspect.inspect(rootObject, options) tabify() putKey(k) puts(' = ') - putValue(t[k], makePath(path, k)) + putValue(t[k]) end if mt then needsComma = commaControl(needsComma) tabify() puts(' = ') - putValue(mt, makePath(path, '')) + putValue(mt) end end) @@ -258,7 +278,7 @@ function inspect.inspect(rootObject, options) end -- putvalue is forward-declared before putTable & putKey - putValue = function(v, path) + putValue = function(v) local tv = type(v) if tv == 'string' then @@ -266,13 +286,13 @@ function inspect.inspect(rootObject, options) elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then puts(tostring(v)) elseif tv == 'table' then - putTable(v, path) + putTable(v) else puts('<',tv,' ',getId(v),'>') end end - putValue(rootObject, {}) + putValue(root, {}) return table.concat(buffer) end diff --git a/spec/inspect_spec.lua b/spec/inspect_spec.lua index 229e4c7..74ed8d4 100644 --- a/spec/inspect_spec.lua +++ b/spec/inspect_spec.lua @@ -180,6 +180,48 @@ describe( 'inspect', function() end) end) + describe('the process option', function() + + it('can be used to remove a particular element easily', function() + local names = {'Andrew', 'Peter', 'Ann' } + local removeAnn = function(item) if item ~= 'Ann' then return item end end + assert.equals(inspect(names, {process = removeAnn}), '{ "Andrew", "Peter" }') + end) + + it('can use the path', function() + local names = {'Andrew', 'Peter', 'Ann' } + local removeThird = function(item, path) if path[1] ~= 3 then return item end end + assert.equals(inspect(names, {process = removeThird}), '{ "Andrew", "Peter" }') + end) + + it('can replace values', function() + local names = {'Andrew', 'Peter', 'Ann' } + local filterAnn = function(item) return item == 'Ann' and '' or item end + assert.equals(inspect(names, {process = filterAnn}), '{ "Andrew", "Peter", "" }') + end) + + it('can nullify metatables', function() + local mt = {'world'} + local t = setmetatable({'hello'}, mt) + local removeMt = function(item) if item ~= mt then return item end end + assert.equals(inspect(t, {process = removeMt}), '{ "hello" }') + end) + + it('can nullify metatables via their paths', function() + local mt = {'world'} + local t = setmetatable({'hello'}, mt) + local removeMt = function(item, path) if path[#path] ~= '' then return item end end + assert.equals(inspect(t, {process = removeMt}), '{ "hello" }') + end) + + it('can nullify the root object', function() + local names = {'Andrew', 'Peter', 'Ann' } + local removeNames = function(item) if item ~= names then return item end end + assert.equals(inspect(names, {process = removeNames}), 'nil') + end) + + end) + describe('metatables', function() it('includes the metatable as an extra hash attribute', function()