• Subject: Re: Tracking number of pairs in a dictionary
• From: Duncan Cross <duncan.cross@...>
• Date: Thu, 1 Oct 2009 18:01:06 +0100

```On Thu, Oct 1, 2009 at 5:09 PM, Jorge <xxopxe@gmail.com> wrote:
> On Wed, 2009-09-30 at 23:34 +0200, Michal Kolodziejczyk wrote:
>> Or you could keep a counter within the table (so you will not iterate
>> the table at all). Here is an example implementation (you can overide
>> removeOne() to what you need):
>>
>> MT={
>
> Wow... Never seen metatables used like that. Had to look it twice to get
> why it works :)
>
> Is there a way for keeping _n and _limit out of the table? With some
> upvalue magic or something? Otherwise you have to explicitly skip them
> while iterating (as the RemoveOne as is does not :) )
>
> Jorge
>
>

You could try using weak-valued tables to store the values of _n and
Modified version of Miko's code follows:

local _ns = setmetatable({}, {__mode = 'k'})
local _limits = setmetatable({}, {__mode = 'k'})

MT={
if not rawget(self, key) then
if _ns[self]>=_limits[self] then
self:removeOne()
end
_ns[self]=_ns[self]+1
end
rawset(self, key, value)
end,
removeOne=function(self)
self[next(self)]=nil
_ns[self]=_ns[self]-1
print('Removed entry')
end,
del=function(self, key)
if rawget(self, key) and _ns[self]>0 then
_ns[self]=_ns[self]-1
end
rawset(self, key, nil)
end
}
MT.__index=MT

LimitedTable={
new=function(limit)
local t = {}
_ns[t] = 0
_limits[t] = limit
return setmetatable(t, MT)
end,
}

-Duncan

```

• References: