[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: idea: __iter generic-for metamethod
 
- From: Jonathan Castello <twisolar@...>
 
- Date: Mon, 24 May 2010 16:53:32 -0700
 
On Mon, May 24, 2010 at 4:38 PM, Stuart P. Bentley
<stuart@testtrack4.com> wrote:
> Depending on how common iterator factories like pairs() are (especially
> among the metatable-using crowd), this proposal might make more sense:
>
>       --proposed addition
>       if type(f)~= "function" then
>         local meta_factory = metatable(f).__iter
>         if not meta_factory and type(f)=="table" then meta_factory = pairs
> end
>         if meta_factory then f, s, var = meta_factory(f) end
>       end
>
> (Also, I forgot an "end" to close the "default" conditional - I've added it
> in the version of the original message as listed below.)
>
I wrote your algorithm into a usable Lua function to try it out. I had
to add a check for nonexistent metatables, but it does work.
----
function stuart_for(body, f, ...)
  local var = {...}
  local s = table.remove(var, 1)
  --proposed addition
  if type(f) ~= "function" then
    local meta_f = getmetatable(f)
    meta_f = meta_f and meta_f.__iter or nil
    if not meta_f and type(f)=="table" then meta_f = pairs end
    if meta_f then f, s, var = meta_f(f) end
  end
  while true do
    local results = {f(s, var)}
    var = results[1]
    if var == nil then break end
    body(unpack(results))
  end
end
----
Usage: stuart_for(function(k, v) print(k, v) end, {1, 1, 2, 3, 5})
Output:
1 1
2 1
3 2
4 3
5 5
Tested by setting __iter for a table to 'ipairs' - thank you for
changing it to use factories, haha - and that works too.
~Jonathan