Tim Menzies
Tim Menzies

Reputation: 730

lua tables, simplest way to overload __tostring

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:

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

Answers (1)

Colonel Thirty Two
Colonel Thirty Two

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

Related Questions