2016-02-10 2 views
2

Благодаря всем пользователям Lua stackoverflow, которые обсудили, как настроить таблицы печати. После долгих чтений я публикую следующее и задаю гуру Lua ....lua tables, самый простой способ перегрузить __tostring

  • это самый простой способ?
  • это слишком просто (т. Е. Сломанный каким-то образом я не понимаю)?

Обратите внимание, что следующий:

  • позволяет для частных полеев (просто начать свое имя с «_»), которые не должны быть напечатаны
  • не добавляет размера к metatable каждому объекту ,

Мой подход переписывает метод по умолчанию tostring.

_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 

выше немного зла (что призыв к PCALL ... не мое гордое немного кода, но, хе, это работает).

В любом случае, теперь tostring делает вызов метода t:s() к объекту, который мы можем определить с помощью следующей доморощенного системы объекта:

Object={} 

function Object:new(o) 
    o = o or {} 
    setmetatable(o,self) 
    self.__index = self 
    return o 
end 

Вот определение по умолчанию :s() - которые могут быть настроены в суб -классов.

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} 
+2

Зачем переписывать tostring вместо настройки метаданных __tostring? – warspyking

+1

Я голосую, чтобы закрыть этот вопрос как не по теме, потому что он показывает рабочую оду, а ОП просит [codereview.se]. – hjpotter92

+2

@ hjpotter92 _working code_ не является допустимой причиной непогоды для переполнения стека. Он просит об улучшении конкретной проблемы/проблемы. Что-то не в тему о просмотре кода в любом случае – Quill

ответ

6

это самый простой способ?

Далеко нет. Самый простой способ - добавить функцию __tostring к вашему метатегу.

function MyClass:__tostring() 
    return "<MyClass: "..self.foo..">" 
end 

не добавляет размера к метатаблице каждому объекта.

Это не проблема. Для каждого класса должен существовать только один метатебель. Использование памяти одной записи в таблице незначительно.

Overwriting tostring является и уродливым, и потенциально опасным: что, если вы (или кто-то еще) используете библиотеку, у объектов которой есть метод s, который имеет побочные эффекты?

+3

Обратите внимание, что '__tostring' в Lua 5.1 не влияет на вызовы' lua_tolstring'. Это было исправлено в 5.2 и более поздних версиях –