lua-users home
lua-l archive

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


2015-03-05 2:34 GMT+02:00 Tom N Harris <telliamed@whoopdedo.org>:

> So ipairs could not be more permissive than pairs in allowing changes
> to the table.

Actually `ipairs` does allow that. `pairs` is different because it depends
on `next`.

| The behavior of next is undefined if, during the traversal, you assign
| any value to a non-existent field in the table.

Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> a={1}
> for k,v in ipairs(a) do
   a[k+1]=k+1
   print(a[k])
   if k==5 then break end
end
1
2
3
4
5
>
There was quite an exhaustive discussion on the new `ipairs` during the
rc-alpha-beta cycle, presumably before the OP joined this list. The fomulation
went through several versions, the final one in the Lua 5.3 reference manual
being succinct and very clear:

| Returns three values (an iterator function, the table t, and 0) so
that the construction
|
|      for i,v in ipairs(t) do body end
|
| will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to
the first nil value.

That is to say, it is approximately equivalent to

     for i=1,math.maxint
         local v = t[k]
         if v==nil then break end
         body
    end

In particular, for any Lua value such that t[1] is nil, it will not do
the body at all.
It is a little surprising that str[1] is nil, not an error, but that
is one of the earlier
surprises that someone with experience of C, Pascal or Python runs into when
starting Lua.

However. `ipairs` is not _exactly_ the same as the loop expansion, since
it uses the generic `for` mechanism. It is a little closer to this:

1. If the argument has an `__index` metamethod, create an iterator
that does the above.
2. If the argument does not have an `__index` metamethod, check
that it is a table, and create an iterator that does the above but with
raw accesses.

I presume the OP was using a Lua 5.3 compiled without -DLUA_COMPAT_5_2,
because on an out-of-the-box Lua, I get:

$ lua
Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> for k,v in ipairs(_VERSION) do print(k,v) end
stdin:1: bad argument #1 to 'ipairs' (table expected, got string)

<rant>
I am not a habitual LuaJIT user, but it has one useful feature that
Lua could take over easily. Here's LuaJIT's startup message:

$ luajit
LuaJIT 2.0.2 -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/
JIT: ON CMOV SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse

The configuration variables are laid out for all to see, whereas the Lua startup
message is exactly the same whether or not -DLUA_COMPAT_5_2 was specified.
</rant>