include evaluation of __tostring for userdata values

Closes #38.
This commit is contained in:
Hisham Muhammad 2019-04-05 16:46:20 -03:00
parent b611db6bfa
commit 6e7f2dce9b
2 changed files with 31 additions and 0 deletions

View File

@ -124,6 +124,19 @@ local function getNonSequentialKeys(t)
return keys, keysLength, sequenceLength return keys, keysLength, sequenceLength
end end
local function getToStringResultSafely(t, mt)
if type(t) ~= "userdata" then
return
end
local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
local str, ok
if type(__tostring) == 'function' then
ok, str = pcall(__tostring, t)
str = ok and str or 'error: ' .. tostring(str)
end
if type(str) == 'string' and #str > 0 then return str end
end
local function countTableAppearances(t, tableAppearances) local function countTableAppearances(t, tableAppearances)
tableAppearances = tableAppearances or {} tableAppearances = tableAppearances or {}
@ -293,6 +306,13 @@ function Inspector:putValue(v)
self:puts(tostring(v)) self:puts(tostring(v))
elseif tv == 'table' then elseif tv == 'table' then
self:putTable(v) self:putTable(v)
elseif tv == 'userdata' then
local mt = getmetatable(v)
local toStringResult = mt and getToStringResultSafely(v, mt)
self:puts('<', tv, ' ', self:getId(v), '>')
if toStringResult then
self:puts(' -- ', escape(toStringResult))
end
else else
self:puts('<', tv, ' ', self:getId(v), '>') self:puts('<', tv, ' ', self:getId(v), '>')
end end

View File

@ -363,6 +363,17 @@ describe( 'inspect', function()
]]), inspect(bar)) ]]), inspect(bar))
end) end)
it('includes the __tostring metamethod of userdata', function()
local tbl = {
f = io.tmpfile(),
}
assert.equals(unindent([[
{
f = <userdata 1> -- $FILE
}
]]):gsub("$FILE", tostring(tbl.f)), inspect(tbl))
end)
it('can be used on the __tostring metamethod of a table without errors', function() it('can be used on the __tostring metamethod of a table without errors', function()
local f = function(x) return inspect(x) end local f = function(x) return inspect(x) end
local tbl = setmetatable({ x = 1 }, { __tostring = f }) local tbl = setmetatable({ x = 1 }, { __tostring = f })