lua-users home
lua-l archive

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



..following a rather ancient thread on this list..


A quick 'grep' of Lua 5.1w4 sources reveals that the '__pairs' metamethod is not in, at least, not yet. Has that plan been trashed for some reason, since I feel it would suit pretty nicely in the Lua ideology.

My issue: making a "table emulating" userdata _really_ behave like a table, also when it comes to iteration. Of course, I could redefine 'pairs'.. hmm.. ;)

-ak


11.7.2003 kello 02:28, RLake@oxfam.org.pe kirjoitti:

 Could rigorous use of a (fictitious) meta method __pairs help
to solve this?  Then pairs(object) can always be used to iterate over
object. (I think __pairs reflects "iteration overriding" better than a
more
low level __next?)

I agree. Whether rigorous use of __pairs would solve all iteration
problems
is an open question, but it is certainly at least as general as using
a __next metamethod, because __pairs could be implemented by default as

  return getmetatable(t).__next, t

So __pairs is at least as powerful as __next, but it could do other things
as well.

(Leaving out a lot of details about checking for metatable existence and
all that.)

The huge advantage of __pairs, other than the fact that it gets to look at the object as a whole rather than in little pieces, is that it only gets
called once per loop, instead of once per loop iteration. That is a big
performance gain. Unfortunately, in the (deprecated) syntax:

  for k, v in t do ... end

What actually happens is

  for k, v in next, t do ... end

Rather than

  for k, v in pairs(t) do ... end

which would arguably have been easier to override.

In answer to Mark's question, what do you need to override:

1) You don't need to use __newindex for a lazy copy, just __index. But if it is a pure proxy, you would need to override whatever metamethods your
object implemented; in the case of tables, that is just __index and
__newindex.

2) You don't *need* to override pairs; all it does is return <next, t>.
The only reason you would have to override pairs is if you had an
iteration problem you couldn't solve with a custom next function.

3) If you need ordered iteration, you need to override table.foreachi and
maybe ipairs as well as table.foreach. In addition, you would probably
need to override a number of other table. functions which implement
vectors-as-tables.

4) Lua does not lend itself to complex metaobject protocol implementations because you cannot stack MOPs. However, that may be considered a feature
if you believe that complex

R.