lua-users home
lua-l archive

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



On 7-Feb-05, at 11:16 AM, Mark Hamburg wrote:

Because next isn't just an implementation detail at this point. It's a
global function and if one wants to override pairs, one might want to
override next. Given that, it would be nice if the override logic for pairs
would recognize a __next override so that programmers wouldn't have to
override both and so that a table iteration with an overridden next wouldn't
do more metatable lookups than necessary.

The simplest solution seems to me to use pairs(t) to get the
relevant next method for the table. If there were a function
call(fn, args...) with the obvious semantics, you could test
for empty tables with:

  if call(pairs(coll)) == nil then
    -- coll is empty
  end

However, this is based on the assumption that next is non-
destructive for all collections, which may not be the case
(for example, if the collection is a file).

I'm not completely sure how to handle that case, aside from
using a wrapper around destructive iterators.

-------

As far as ipairs goes, I don't believe that ipairs is
symmetrical with pairs. My issue with ipairs is that it
currently uses rawgeti() internally, which means it won't
work with alternative table implementations. I'm not sure
that the complication of the optimization is worth it; it
would be easy to define ipairs in a collection-independent
way, and provide an efficient implementation as a service
for implementers of vector-like collections. One of the
following should be appropriate (depending on the desired
semantics); actually, both of them could be included in
an iteration library. (The idea would be to use the
appropriate one as the __pairs metamethod):

-- based on stopping at the first nil
  local function int_iterator(coll, index)
    index = index + 1
    local val = coll[index]
    if val ~= nil then return index, val end
  end

  function ipairs(coll)
    return int_iterator, coll, 0
  end

-- based on some standard function for extracting
-- the size of a collection; the weakness of this
-- implementation is that it can't be used with
-- collections which change size during the iteration
-- (such as work queues)
  function ipairs(coll)
    local limit = getn(coll)
    local function iter(coll, index)
      index = index + 1
      if index < limit then
        return index, coll[index]
      end
    end
    return iter, coll, 0
  end