Reputation: 730
Thanks to all the Lua stackoverflow folks who have discussed how to customized printing tables. After much reading, I post the following and ask the Lua gurus....
Note that the following:
metatable
of every object.My approach rewrites the default tostring
method.
_tostring = _tostring or tostring
function tostring(t)
if type(t) == "table" then
status, stuff = pcall(function() return t:s() end)
if status then
return stuff
end end
return _tostring(t)
end
The above is a little evil (that call to pcall... not my proudest bit of code but, heh, it works).
In any case, now tostring
makes the method call t:s()
to an object which we can define using the following homebrew object system:
Object={}
function Object:new(o)
o = o or {}
setmetatable(o,self)
self.__index = self
return o
end
Here's the default definition of :s()
-- which can be customized in sub-classes.
function Object:s()
-- can be customized in subclasses
local out,sep="{",":"
for x,y in pairs(self) do
if string.sub(x,1,1) ~= "_" then
out = out..sep..x.." "..y
sep = " :"
end end
return out .. '}'
end
e.g.
x=Object:new{a=1, _b=2};print(x)
{:a 1}
Upvotes: 5
Views: 11332
Reputation: 26609
is this the simplest way?
By far, no. The simplest way would be to add a __tostring
function to your metatable.
function MyClass:__tostring()
return "<MyClass: "..self.foo..">"
end
does not add size to the metatable of every object.
This is not a concern. Only one metatable should exist per class. The memory usage of one entry in a table is negligible.
Overwriting tostring
is both ugly and potentially dangerous: what if you (or someone else) is using a library whose objects have an s
method that has side effects?
Upvotes: 14