lua-users home
lua-l archive

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


On Sat, Jan 9, 2010 at 8:25 AM, steve donovan wrote:
> local array = {}
> local rawset,rawget,ipairs = rawset,rawget,ipairs
> in array do
>    function __len(t) return #t.store end
>    function __newindex(t,i,val) rawset(t.store,i,val) end
>    function __index(t,i) return rawget(t.store,i) end
>    function __ipairs(t) return ipairs(t.store) end
> end
> function new_array ()
>    return setmetatable({store={}},array)
> end
> t = new_array()

Concerning this use case, it could be written more compactly as

  local array = {}
  in class(array) do
    function __len(t) return #t.store end
    function __newindex(t,i,val) rawset(t.store,i,val) end
    function __index(t,i) return rawget(t.store,i) end
    function __ipairs(t) return ipairs(t.store) end
    function __init() return object{store={}} end
  end
  t = array()

But the following approach in Lua 5.1 is conceptually more flexible
(e.g. what if array is userdata?):

  local array = class(function()
    function __len(t) return #t.store end
    function __newindex(t,i,val) rawset(t.store,i,val) end
    function __index(t,i) return rawget(t.store,i) end
    function __ipairs(t) return ipairs(t.store) end
    function __init() return object{store={}} end
  end)
  t = array()

or if you like to avoid globals, we can introduce lexicals as function
arguments:

 local array = class(function(s)
    function s.__len(t) return #t.store end
    function s.__newindex(t,i,val) rawset(t.store,i,val) end
    function s.__index(t,i) return rawget(t.store,i) end
    function s.__ipairs(t) return ipairs(t.store) end
    function s.__init() return setmetatable({store={}},array) end
  end)
  t = array()

The "end)" syntax was always a little odd, but there are ways it could
be avoided:

 local array = class ::
    function __len(t) return #t.store end
    function __newindex(t,i,val) rawset(t.store,i,val) end
    function __index(t,i) return rawget(t.store,i) end
    function __ipairs(t) return ipairs(t.store) end
    function __init() return setmetatable({store={}},array) end
  end

where "::" is basically like a "function()" but allows omitting
parenthesis in the call.