lua-users home
lua-l archive

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


Am 16.12.10 20:38, schrieb HyperHacker:
> 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...

I do all my hackery in C, and my prime goal is to have readable Lua
code, that looks like Lua.  Since ClearSilver now works reasonably well
(the example above is from a web app), PostgreSQL is next on my list...