问题描述:

I am looking for a metamethod (or a workaround) that fires when removing an element from a lua table similar to the __newindex metamethod.

Ideally it would work something like the following:

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

I have tried working with the __gc metamethod but that is not usable in this implementation due to the fact that the metamethod only triggers when the garbage collection cycle happens. I have no control over the garbage collection because the table (with the metamethods) is passed to a different script.

网友答案:

Possible workaround - do not store actual data within table.

Let your mytable act as a proxy, and store actual values in some shadow table. It might be allocated along with mytable, or data can be stored directly in metatable (so metatable must be created per mytable instance). Here's example (easily broken by writing data under metamethods' name keys, but you get an idea), data will be stored within metatable: 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)
网友答案:

As assigning nil fires not metamethod at all, you will have to resort to an explicit removal function that does whatever you wanted the metamethod to do and then assign nil to the table entry.

相关阅读:
Top