[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Proxying in Lua 5.1 vs Lua 5.2 (Was: Re: Possible bug with the length operator)
- From: HyperHacker <hyperhacker@...>
- Date: Sat, 2 Apr 2011 19:10:54 -0600
On Sat, Apr 2, 2011 at 19:06, Jan Behrens <public@magnetkern.de> wrote:
>> >> On Fri, Apr 1, 2011 at 08:58, Julien Duminil <julien.duminil@ubisoft.com> wrote:
>> >> > But I was wondering if __len and __newindex are enough to easily
>> >> > emulate all four of these options, as you can't detect adding some
>> >> > "holes" in your table. So here is my question: would it be
>> >> > interesting to add a __delindex or __remindex metamethod called when
>> >> > an existing table index/key is setted to nil?
>> >
>> > On Friday 01 April 2011 17:28:57 HyperHacker wrote:
>> >> __newindex is called even if the value being set is nil. The problem
>> >> is that __newindex isn't called if the key already exists (presumably
>> >> for optimization). So you need to use __index and __newindex to proxy
>> >> all accesses to a hidden table somewhere so that you can catch those
>> >> nil assignments. Then you're free to handle "holes" however you like.
>> >
>> On 1 April 2011 14:10, Jan Behrens <public@magnetkern.de> wrote:
>> > One way to do it is this one:
>> >
>> > do
>> > local data = setmetatable({}, {__mode = "k"}) -- ephemeron table since Lua 5.2
>> > local mt = {
>> > __index = function(t, k)
>> > return data[t][k]
>> > end,
>> > __newindex = function(t, k, v)
>> > if v == nil then
>> > print("NOTICE: Deleted key " .. tostring(k) .. " in (proxy) table " .. tostring(t))
>> > end
>> > data[t][k] = v
>> > end,
>> > -- TODO: add __len, __pairs, __ipairs as needed (needs Lua 5.2)
>> > }
>> > function makeproxy(t) -- NOTE: don't mix with undocumented function "newproxy"
>> > local proxy = setmetatable({}, mt)
>> > data[proxy] = {}
>> > for k, v in pairs(t) do
>> > data[proxy][k] = v
>> > end
>> > return proxy
>> > end
>> > end
>> >
>> >
>> > The results are as follows:
>> >
>> > Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> >
>> >> t = makeproxy{"Hello", "World"}
>> >> t[1] = nil
>> >
>> > NOTICE: Deleted key 1 in (proxy) table table: 0x800e12a00
>> >
>> >
>> > If I understand correctly, there are two problems with this
>> > approach in Lua 5.1, which will BOTH be solved in Lua 5.2:
>> >
>> > a) Lua 5.1 supports no ephemeron tables, which means that
>> > t[1] = t; t = nil would cause a memory leak, as there are
>> > remaining references to t in the proxied table.
>> > b) The metamethod __len does not work for tables and the
>> > metamethods __pairs and __ipairs do not exist in Lua 5.1.
>
> On Sunday 03 April 2011 02:10:57 Henk Boom wrote:
>> What about next(t)?
>>
>> henk
>
> As I know the 'next' function will not honor any __next
> metamethod in Lua 5.2, so this will not be possible. Making
> 'next' to honor a possibly existing metamethod would be a
> performance problem anyway, I guess.
>
> Of course you could overwrite 'next' with your own function,
> but that won't work for libraries which import the 'next'
> function by writing
>
> local next = _G.next
>
> as the reference to the old next function will be copied.
> That is why I think introducing __ipairs and __pairs
> metamethods is a good decision for Lua 5.2 alpha.
>
>
> Jan Behrens
>
>
Hmm, that's kind of surprising that there isn't a __next to accompany
__pairs and __ipairs, especially since pairs() uses next() as its
iterator.
--
Sent from my toaster.