lua-users home
lua-l archive

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


On Sat, May 22, 2010 at 12:21 PM, Stuart P. Bentley
<stuart@testtrack4.com> wrote:
> I like this. In fact, I'd say that replacing the __pairs and __ipairs
> metamethods with an __iter metamethod (that is used by the generic "for"
> when encountering non-functions, with the default case of next()) would be
> "cleaner" (as you're now not mixing up standard library functions like pairs
> with language features like metatables).
>
> On Sat, 22 May 2010 11:48:11 -0700, Jonathan Castello <twisolar@gmail.com>
> wrote:
>
>> On Sat, May 22, 2010 at 11:33 AM, Joshua Jensen
>> <jjensen@workspacewhiz.com> wrote:
>>>
>>> I am still fond of 'for k,v in t do'.  I was very sad to see it go.  It
>>> was
>>> simple.  Lua is supposed to be simple, but ipairs/pairs complicated it.
>>>
>>> Josh
>>>
>>
>> Could we perhaps return to "for k,v in t do", and have the generic-for
>> use the __pairs metamethod of its target as the iterator factory? If
>> no __pairs exists, default to next(). So this:
>>
>> for k,v in t do
>>  print(k, v)
>> end
>>
>> would normally act like you used pairs(). But if you set a metatable:
>>
>> setmetatable(t, {
>>  __pairs = function(t)
>>    return function(t, i)
>>      i = i + 1
>>      local v = t[i]
>>      if v then
>>        return i, v
>>      end
>>    end, t, 0
>>  end,
>> })
>>
>> then it iterates over the numeric indices in order. Further, you could
>> easily define a "false ipairs()" that returns a table with the __pairs
>> metamethod set:
>>
>> function ipairs(t)
>>  local copy = {}
>>  for k,v in t do
>>    copy[k] = v
>>  end
>>  return setmetatable(copy, {
>>    __pairs = the_iter, -- same as above
>>  })
>> end
>>
>> ~Jonathan
>
>

I agree, __iter sounds like a much better choice of name.

As a point of interest, if numbers had a default __iter of their own,
you could do voodoo like this:

for i in 50, 100 do
  print(i)
end

Presumably, __iter would be called with 100 as the second argument,
just like you'd expect for an iterator factory. You could even pass a
third value, the step:

for i in 1, 100, 5 do
  print(i)
end

That pretty much obsoletes the numeric-for, actually.

~Jonathan