1
0

Fixed bugs relating to weird __tostring metamethods.

This commit is contained in:
Jon Michael Aanes 2017-10-21 13:24:33 +02:00
parent d0b83f7f0d
commit 79b036e51e
2 changed files with 20 additions and 3 deletions

View File

@ -217,13 +217,31 @@ local function is_leaf_node (t)
return true
end
local function super_tostring (t)
-- Normally taking `tostring` of a value returns a string, but Lua does not
-- enforce that __tostring must return a string, so this function attempts
-- to find a definitive `tostring` representation, even if metatable
-- shenanigans has occurred.
-- Is guaranteed to either return a string or a nil. Nil only occurs if the
-- function cannot find a string.
local seen = { [t] = true }
while true do
local nt = tostring(t)
if type(nt) == 'string' or nt == nil then return tostring(nt) end
if seen[nt] then return nil end
seen[nt], t = true, nt
end
end
--------------------------------------------------------------------------------
local function get_table_info (t)
local key_types = get_key_types(t)
local info = {}
info.address = tostring(t):sub(8)
info.string_repr = super_tostring(t)
info.address = info.string_repr and info.string_repr:match '^table: 0x(%x+)$' or nil
info.nr_elems = nr_elements_in_table(t)
info.seq_elems, info.has_holes = nr_elements_in_seq(t)
info.map_elems = info.nr_elems - info.seq_elems
@ -288,7 +306,6 @@ local function analyze_structure (root, max_depth, info)
-- Use depth collected
for node in pairs(depth) do
info[node].depth = depth[node]
info[node].address = info[node].address .. ': ' .. info[node].depth
end
assert(type(info) == 'table')

View File

@ -87,7 +87,7 @@ format_test {
format_test {
name = 'Proper sorting of number strings keys',
input = { ['-100'] = 'b', ['-1'] = 'c', ['0'] = 'd', ['1'] = 'e', ['100'] = 'f' },
input = { ['-100'] = 'a', ['-1'] = 'b', ['0'] = 'c', ['1'] = 'd', ['100'] = 'e' },
expect = '{\n [\'-100\'] = \'b\', [\'-1\'] = \'c\',\n [\'0\'] = \'d\', [\'1\'] = \'e\',\n [\'100\'] = \'f\'\n}',
}