lua-users home
lua-l archive

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

On 02/16/2016 10:19 AM, Dirk Laurie wrote:

Example 1. XML tables. These are lists in which the items
are either scalars or XML tables, and which also have some
"attributes", i.e. string-valued keys associated with scalar values.
The context is very often one in which the items take default
attributes from the containing value by specifying it as __index.

I've never seen this practice, and wouldn't desire it myself.

Example 2. Plugging holes in lists of numbers.
     x = setmetatable({5,9,nil,6,nil,nil,3,1},
     {__index = load"return 0/0",
      __len=load"return 8"})
     print(table.concat(x," "))
5 9 -nan 6 -nan -nan 3 1
Without that "index", you can't concatenate the table.

However, try this:
for k,v in ipairs(y) do print(k,v) end
and see what happens.

It's a little more code, but it works:
tlen = 8;
x = setmetatable({5,9,nil,6,nil,nil,3,1},
    {__index = function(t,k)
            if type(k)=="number" and k<=tlen then return 0/0; end
     __len = function() return tlen; end;

Furthermore, if the # operator respects __index (section 3.4.7 is a little ambiguous on this, neither specifying that it does nor that it doesn't), neither the upvalue tlen nor the __len() function are necessary. In your example, __len also isn't necessary, i.e. this works although I don't think it can be relied upon based on the manual:
x = setmetatable({5,9,nil,6,nil,nil,3,1},
    {__index = function(t,k)
            if type(k)=="number" and k<=8 then return 0/0; end

If only we still had __ipairs, neat solutions to the problem
would have been possible.

Solutions ("neat" is a matter of opinion) are still possible, see above example.

You didn't specify what would be your alternative "neat" solution if __ipairs() still existed. If you don't specify *both* __ipairs *and* __index, you would not have filled the holes, since x[3] would still return nil, while `for i,v in ipairs(x)` would produce 3,nan. So my guess is that your "neat" solution would have at least as much code as my "unkempt" one.

As it stands, the straightforward
numeric `for` is the only answer.

No it isn't [see above example] but even if it were, what's wrong with numeric `for`s?

While I have no big problem with __ipairs, I do think that the default ipairs() should respect __index. Given that it does, there are only a tiny minority of cases when it is simpler to use __ipairs than __index, so it seems cleaner to remove it.

-- David