lua-users home
lua-l archive

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


> pairs and ipairs are "intended" for iterating over table-like objects.
> __pairs and __ipairs allow non-tables to behave like tables do in more
> situations. If you want to attach them to a more complex object, then
> simply set __pairs and __ipairs to the same function if you want to
> make pairs() and ipairs() both do the default iteration. For complex
> objects, it may not be obvious (to people other than the library
> author) what the default iteration is. In this case, it can be clearer
> if the complex object has members on it for iteration, like "for k,v
> in obj:children() do" or "for callback in obj:callbacks() do", thus
> making it explicit what part of the object is being iterated.
 
Looking at it fundamentally, any object that implements collection semantics
benefits from iterator functionality. "pairs" is appropriate for
dictionary-like collections (whether implemented using tables or otherwise)
while "ipairs" is appropriate for "list" or "array" like collections
(whether implemented using tables or otherwise). With basic Lua whether a
table is "dictionary-like" or "list-like" is about how you assign the keys,
but with true object orientation (using metatables) you will usually decide
the structure of the table in the class design. OK sometimes an object
requires more than one type of iterator, but rarely exactly "pairs" and
"ipairs" - so it would be better to cope with this by allowing "__iter" to
be parameterised (or as you suggest, using methods for non-default
iterators).

The Lua "String" type got an object oriented library in the last version,
but think about how the same would have to be done for "Table". You would
need to fork the Table type into two Classes- many of the functions in the
library only work on "List-Like" tables so you'd want one metatable for
those and another for "Generic" "Dictionary-like" tables. "pairs" would be
the right iterator in the generic class and "ipairs" in the "List-Like"
case.

> The parser doesn't know what type of value "t" is in "for k, v in t
> do", let alone if it has an __iter metamethod or not.

OK, but the case is no different from any other "core" metamethod i.e.
"__add". I admit I've never looked into the details, but if this metamethod
has to be resolved at runtime so could the "__iter" metamethod be. Maybe
that involves a new bytecode, but that is what new versions are for surely?
I get that "__pairs" and "__ipairs" are "library metamethods" in the same
sense as "__tostring" is, but this means they are rather trivial and could
be implemented easily on the current language platform just by shelling the
pairs and ipairs functions.