fix endless recursion when using inspect to reimplement global tostring

This commit is contained in:
Andreas Hofer 2016-03-29 22:53:26 +02:00
parent a998635207
commit d051ae061c
2 changed files with 22 additions and 5 deletions

View File

@ -28,6 +28,8 @@ local inspect ={
]] ]]
} }
inspect.tostring = _G.tostring
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})
@ -110,7 +112,7 @@ local function getToStringResultSafely(t, mt)
local str, ok local str, ok
if type(__tostring) == 'function' then if type(__tostring) == 'function' then
ok, str = pcall(__tostring, t) ok, str = pcall(__tostring, t)
str = ok and str or 'error: ' .. tostring(str) str = ok and str or 'error: ' .. inspect.tostring(str)
end end
if type(str) == 'string' and #str > 0 then return str end if type(str) == 'string' and #str > 0 then return str end
end end
@ -198,7 +200,7 @@ function Inspector:puts(...)
local len = #buffer local len = #buffer
for i=1, #args do for i=1, #args do
len = len + 1 len = len + 1
buffer[len] = tostring(args[i]) buffer[len] = args[i]
end end
end end
@ -224,7 +226,7 @@ function Inspector:getId(v)
self.maxIds[tv] = id self.maxIds[tv] = id
self.ids[tv][v] = id self.ids[tv][v] = id
end end
return id return inspect.tostring(id)
end end
function Inspector:putKey(k) function Inspector:putKey(k)
@ -236,7 +238,7 @@ end
function Inspector:putTable(t) function Inspector:putTable(t)
if t == inspect.KEY or t == inspect.METATABLE then if t == inspect.KEY or t == inspect.METATABLE then
self:puts(tostring(t)) self:puts(inspect.tostring(t))
elseif self:alreadyVisited(t) then elseif self:alreadyVisited(t) then
self:puts('<table ', self:getId(t), '>') self:puts('<table ', self:getId(t), '>')
elseif self.level >= self.depth then elseif self.level >= self.depth then
@ -296,7 +298,7 @@ function Inspector:putValue(v)
if tv == 'string' then if tv == 'string' then
self:puts(smartQuote(escape(v))) self:puts(smartQuote(escape(v)))
elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
self:puts(tostring(v)) self:puts(inspect.tostring(v))
elseif tv == 'table' then elseif tv == 'table' then
self:putTable(v) self:putTable(v)
else else

View File

@ -411,4 +411,19 @@ describe( 'inspect', function()
end) end)
end) end)
end) end)
it('allows changing the global tostring', function()
local save = _G.tostring
_G.tostring = function(x)
if type(x) == "string" then
return x
else
return inspect(x)
end
end
local s = tostring({1, 2, 3})
_G.tostring = save
assert.equals("{ 1, 2, 3 }", s)
end)
end) end)