mirror of
https://github.com/kikito/inspect.lua.git
synced 2024-12-15 14:34:21 +00:00
Stops relying on rawlen/# to calculate the length of the sequence part of a table
Fixes #24
This commit is contained in:
parent
74643aea09
commit
5673f2364d
35
inspect.lua
35
inspect.lua
@ -31,9 +31,6 @@ local inspect ={
|
|||||||
inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})
|
inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})
|
||||||
inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})
|
inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})
|
||||||
|
|
||||||
-- returns the length of a table, ignoring __len (if it exists)
|
|
||||||
local rawlen = _G.rawlen or function(t) return #t end
|
|
||||||
|
|
||||||
-- Apostrophizes the string if it has quotes, but not aphostrophes
|
-- Apostrophizes the string if it has quotes, but not aphostrophes
|
||||||
-- Otherwise, it returns a regular quoted string
|
-- Otherwise, it returns a regular quoted string
|
||||||
local function smartQuote(str)
|
local function smartQuote(str)
|
||||||
@ -57,10 +54,10 @@ local function isIdentifier(str)
|
|||||||
return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
|
return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isSequenceKey(k, length)
|
local function isSequenceKey(k, sequenceLength)
|
||||||
return type(k) == 'number'
|
return type(k) == 'number'
|
||||||
and 1 <= k
|
and 1 <= k
|
||||||
and k <= length
|
and k <= sequenceLength
|
||||||
and math.floor(k) == k
|
and math.floor(k) == k
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -86,13 +83,26 @@ local function sortKeys(a, b)
|
|||||||
return ta < tb
|
return ta < tb
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- For implementation reasons, the behavior of rawlen & # is "undefined" when
|
||||||
|
-- tables aren't pure sequences. So we implement our own # operator.
|
||||||
|
local function getSequenceLength(t)
|
||||||
|
local len = 1
|
||||||
|
local v = rawget(t,len)
|
||||||
|
while v ~= nil do
|
||||||
|
len = len + 1
|
||||||
|
v = rawget(t,len)
|
||||||
|
end
|
||||||
|
return len - 1
|
||||||
|
end
|
||||||
|
|
||||||
local function getNonSequentialKeys(t)
|
local function getNonSequentialKeys(t)
|
||||||
local keys, length = {}, rawlen(t)
|
local keys = {}
|
||||||
|
local sequenceLength = getSequenceLength(t)
|
||||||
for k,_ in pairs(t) do
|
for k,_ in pairs(t) do
|
||||||
if not isSequenceKey(k, length) then table.insert(keys, k) end
|
if not isSequenceKey(k, sequenceLength) then table.insert(keys, k) end
|
||||||
end
|
end
|
||||||
table.sort(keys, sortKeys)
|
table.sort(keys, sortKeys)
|
||||||
return keys
|
return keys, sequenceLength
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getToStringResultSafely(t, mt)
|
local function getToStringResultSafely(t, mt)
|
||||||
@ -234,8 +244,7 @@ function Inspector:putTable(t)
|
|||||||
else
|
else
|
||||||
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
|
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
|
||||||
|
|
||||||
local nonSequentialKeys = getNonSequentialKeys(t)
|
local nonSequentialKeys, sequenceLength = getNonSequentialKeys(t)
|
||||||
local length = rawlen(t)
|
|
||||||
local mt = getmetatable(t)
|
local mt = getmetatable(t)
|
||||||
local toStringResult = getToStringResultSafely(t, mt)
|
local toStringResult = getToStringResultSafely(t, mt)
|
||||||
|
|
||||||
@ -243,11 +252,11 @@ function Inspector:putTable(t)
|
|||||||
self:down(function()
|
self:down(function()
|
||||||
if toStringResult then
|
if toStringResult then
|
||||||
self:puts(' -- ', escape(toStringResult))
|
self:puts(' -- ', escape(toStringResult))
|
||||||
if length >= 1 then self:tabify() end
|
if sequenceLength >= 1 then self:tabify() end
|
||||||
end
|
end
|
||||||
|
|
||||||
local count = 0
|
local count = 0
|
||||||
for i=1, length do
|
for i=1, sequenceLength do
|
||||||
if count > 0 then self:puts(',') end
|
if count > 0 then self:puts(',') end
|
||||||
self:puts(' ')
|
self:puts(' ')
|
||||||
self:putValue(t[i])
|
self:putValue(t[i])
|
||||||
@ -273,7 +282,7 @@ function Inspector:putTable(t)
|
|||||||
|
|
||||||
if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing }
|
if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing }
|
||||||
self:tabify()
|
self:tabify()
|
||||||
elseif length > 0 then -- array tables have one extra space before closing }
|
elseif sequenceLength > 0 then -- array tables have one extra space before closing }
|
||||||
self:puts(' ')
|
self:puts(' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -86,6 +86,15 @@ describe( 'inspect', function()
|
|||||||
assert.equals("{\n a = 1,\n b = 2\n}", inspect({a = 1, b = 2}))
|
assert.equals("{\n a = 1,\n b = 2\n}", inspect({a = 1, b = 2}))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('identifies tables with no number 1 as struct-like', function()
|
||||||
|
assert.equals(unindent([[{
|
||||||
|
[2] = 1,
|
||||||
|
[25] = 1,
|
||||||
|
id = 1
|
||||||
|
}
|
||||||
|
]]), inspect({[2]=1,[25]=1,id=1}))
|
||||||
|
end)
|
||||||
|
|
||||||
it('identifies numeric non-array keys as dictionary keys', function()
|
it('identifies numeric non-array keys as dictionary keys', function()
|
||||||
assert.equals("{ 1, 2,\n [-1] = true\n}", inspect({1, 2, [-1] = true}))
|
assert.equals("{ 1, 2,\n [-1] = true\n}", inspect({1, 2, [-1] = true}))
|
||||||
assert.equals("{ 1, 2,\n [1.5] = true\n}", inspect({1, 2, [1.5] = true}))
|
assert.equals("{ 1, 2,\n [1.5] = true\n}", inspect({1, 2, [1.5] = true}))
|
||||||
@ -131,6 +140,8 @@ describe( 'inspect', function()
|
|||||||
c = 3
|
c = 3
|
||||||
}
|
}
|
||||||
]]), inspect({ 'a', {b = 1}, 2, c = 3, ['ahoy you'] = 4 }))
|
]]), inspect({ 'a', {b = 1}, 2, c = 3, ['ahoy you'] = 4 }))
|
||||||
|
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('displays <table x> instead of repeating an already existing table', function()
|
it('displays <table x> instead of repeating an already existing table', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user