[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Detecting read or write access in __index metamethod
- From: HyperHacker <hyperhacker@...>
- Date: Thu, 16 Dec 2010 12:45:00 -0700
On Thu, Dec 16, 2010 at 12:43, Axel Kittenberger <axkibe@gmail.com> wrote:
> You can also reuse the same temporary table. IMHO No need to create it
> every time.
>
> On Thu, Dec 16, 2010 at 8:38 PM, HyperHacker <hyperhacker@gmail.com> wrote:
>> On Thu, Dec 16, 2010 at 12:09, Marc Balmer <marc@msys.ch> wrote:
>>> Am 15.12.10 18:27, schrieb Luiz Henrique de Figueiredo:
>>>>> The much graver problem than only creating on write access is that you
>>>>> want a.b.c.d to nil if not defined. Not some sort of tracking table.
>>>>> This cannot work, since there is no way to tell in an __index if this
>>>>> is the last element or not and to return some table that helps
>>>>> tracking following indexes or if it should return nil already.
>>>>
>>>> Can't you set an __index for nil that returns nil?
>>>> I think this has been suggested before, perhaps by me :-)
>>>>
>>>>> debug.setmetatable(nil,{__index=function () return nil end})
>>>>> =a.b
>>>> nil
>>>>> return a.b.c
>>>> nil
>>>>
>>>
>>> fyi, I solved this problem. I did not put to much magic in my code. So
>>> instead of writing
>>>
>>> for n = 1, res:ntuples() do
>>> hdf.bset[n].id = res:getvalue(n, 1)
>>> hdf.bset[n].name = res:getvalue(n, 2)
>>> hdf.bset[n].description = res:getvalue(n, 3)
>>> end
>>>
>>> I write
>>>
>>> hdf.bset = {}
>>> for n = 1, res:ntuples() do
>>> hdf.bset[n] = {}
>>> hdf.bset[n].id = res:getvalue(n, 1)
>>> hdf.bset[n].name = res:getvalue(n, 2)
>>> hdf.bset[n].description = res:getvalue(n, 3)
>>> end
>>>
>>> Which is more explicit anyway and looks more like "stock" Lua. So no
>>> magic in table creation and it worked.
>>>
>>>
>>
>> I solved a similar problem just yesterday:
>> --set up an ugly slow metatable hack for pixel access.
>> --writing isn't implemented and it assumes RGBA 8888 but it probably works.
>> Obj.Pixels = setmetatable({_s=Obj}, {__index = function(tbl, x)
>> return setmetatable({_s=tbl._s, _x=x}, {__index = function(tbl, y)
>> return setmetatable({_s=tbl._s, _x=tbl._x, _y=y}, {
>> __index=function(tbl, c)
>> local idx = ({r=0, g=1, b=2, a=3})[c]
>> if not idx then return nil end
>> idx = (tbl._y * tbl._s.Width) + tbl._x + idx
>> return tbl._s.RawPixels[idx]
>> end})
>> end})
>> end})
>> This is ugly and inefficient, but works as intended. What it does is
>> allow me to write foo.Pixels[x][y].b instead of
>> foo.RawPixels[(y*foo.Width)+x+2].
>> - foo.Pixels[x] returns a temporary table, containing _s=foo and _x=x;
>> [y] calls this table's __index which returns another temporary table,
>> same as the last but with the added _y=y; .b again indexes the
>> temporary table and uses the _x, _y and key ('b' here) to compute the
>> byte index requested in _s.
>>
>> So if you don't mind creating and destroying three temporary tables
>> for every pixel element access, you can do this...
>>
>> --
>> Sent from my toaster.
>>
>>
>
>
Good catch. I'll make a note to change that.
--
Sent from my toaster.