diff --git a/inspect.lua b/inspect.lua index ea874b2..ea2df3d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -136,23 +136,34 @@ local function countTableAppearances(t, tableAppearances) return tableAppearances end +local copySequence = function(s) + local copy, len = {}, #s + for i=1, len do copy[i] = copy[i] end + return copy, len +end + local function makePath(path, key) - local newPath, len = {}, #path - for i=1, len do newPath[i] = path[i] end - newPath[len+1] = key + local newPath, len = copySequence(path) + newPath[len + 1] = key return newPath end -local function processRecursive(object, path, process) - local processed = process(object, path) +local function processRecursive(process, item, path) + if item == nil then return nil end + + local processed = process(item, path) if type(processed) == 'table' then local processedCopy = {} + local processedKey for k,v in pairs(processed) do - processedCopy[k] = processRecursive(v, makePath(path, k), process) + processedKey = processRecursive(process, k, makePath(path, '')) + if processedKey ~= nil then + processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey)) + end end - local mt = processRecursive(getmetatable(processed), makePath(path, ''), process) + local mt = processRecursive(process, getmetatable(processed), makePath(path, '')) setmetatable(processedCopy, mt) processed = processedCopy end @@ -165,7 +176,7 @@ function inspect.inspect(root, options) local depth = options.depth or math.huge local process = options.process if process then - root = processRecursive(root, {}, process) + root = processRecursive(process, root, {}) end local tableAppearances = countTableAppearances(root) diff --git a/spec/inspect_spec.lua b/spec/inspect_spec.lua index c16871c..f387592 100644 --- a/spec/inspect_spec.lua +++ b/spec/inspect_spec.lua @@ -220,6 +220,27 @@ describe( 'inspect', function() assert.equals(inspect(names, {process = removeNames}), 'nil') end) + it('changes keys', function() + local dict = {a = 1} + local changeKey = function(item, path) return item == 'a' and 'x' or item end + assert.equals(inspect(dict, {process = changeKey}), '{\n x = 1\n}') + end) + + it('nullifies keys', function() + local dict = {a = 1, b = 2} + local removeA = function(item, path) return item ~= 'a' and item or nil end + assert.equals(inspect(dict, {process = removeA}), '{\n b = 2\n}') + end) + + it('marks key paths with ', function() + local names = {a = 1} + local paths = {} + local addPath = function(item, path) paths[#paths + 1] = path; return item end + + inspect(names, {process = addPath}) + + assert.same(paths, { {}, {''}, {'a'} }) + end) end) describe('metatables', function()