2017-02-22 22 views
1

Я ищу метамод (или обходной путь), который срабатывает при удалении элемента из таблицы lua, аналогичного метатету __newindex.Lua metamethod, который срабатывает при удалении элемента из таблицы

В идеале это будет работать что-то вроде следующего:

local mytable = {} 

local mt = { 
    __newindex = function(t,k,v) 
    rawset(t,k,v) 
    -- some other functionality 
    end, 

    -- This does not exist 
    __remove = function(t,k) 
    --some functionality 
    end 
} 

setmetatable(mytable,mt) 

-- __newindex fires 
mytable["key"] = value 

-- __remove fires 
mytable["key"] = nil 

Я попытался работать с __gc Метаметод но не может использоваться в этой реализации из-за того, что Метаметод только срабатывает, когда сбор мусора цикла случается. У меня нет контроля над сборкой мусора, потому что таблица (с метаметодами) передается другому сценарию.

ответ

1

Возможное обходное решение - не хранить фактические данные в таблице.

Пусть ваш mytable действует как прокси-сервер и сохраняет фактические значения в теневой таблице. Он может быть выделен вместе с mytable, или данные могут быть сохранены непосредственно в metatable (поэтому метатет должен быть создан на экземпляр mytable). Вот пример (легко ломается, записывая данные под клавишами имени метаметодов, но вы получите идею), данные будут храниться в метатаблицах: http://ideone.com/eCOal3

local mytable = {} 

local mt = {} 

function mt.__newindex(t,k,new_value) 
    local previous_value = mt[k] 
    rawset(mt,k,new_value) 

    if previous_value and new_value == nil then 
     print "__remove() triggered" 
    end 
end 
mt.__index = mt 

setmetatable(mytable, mt) 

mytable.key = 123 
print(mytable.key) 

mytable.key = nil 
print(mytable.key) 
+0

Спасибо. Это решает мою проблему. – Frik

1

Как назначить нулевые огни, а не метаметоды вообще, вам придется прибегнуть к явной функции удаления, которая делает все, что вы хотите, чтобы метаметод выполнял, а затем назначил nil записи в таблице.

 Смежные вопросы

  • Нет связанных вопросов^_^