lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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={
>>   add=function(self, key, value)
>
> 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
_limit instead of fields.
Modified version of Miko's code follows:


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

MT={
 add=function(self, key, value)
   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