On Jan 9, 2010, at 1:52 AM, Alexander Gladysh wrote:
>> Mark's remark
>> about pack/unpack being paired has some relevance here: pack() must
>> set 'n', so why can't unpack() use it? Or ipairs?
>
> And we're back to 4.x times?
>
> I guess the problem is that if you accidentally have the "n" field
> that is totally unrelated to the table size (which is and must be a
> perfectly legal thing to do), you would not be able to do *anything*
> (aside of changing the table) to prevent unpack() or ipairs() from
> looking at it.
>
> If we're going this way, then, better solution, perhaps, would be to
> have a custom length "attribute" on a table, which would not be
> neither a key nor a value.
>
> But wait, now we're have one! The __len metamethod! Of course, this
> has overhead of dealing with metatables, but, then, see (1).
Yes, n is problematic because it isn't going to work with idioms like t[ #t + 1 ] = x.
On the other hand, if the goal of pack is to pair with unpack, then it would be nice if they paired well. Right now, one needs to write:
x = table.pack( ... )
-- some time later
table.unpack( x, 1, x.n )
That seems unbalanced.
Note that my proposal to have unpack look for n is only if the range isn't provided, so one could always write unpack( t, 1, #t ) to get the current behavior.
Another option is a separate pair of functions: packn and unpackn.
Or maybe pack sets a metatable that implements __len, but then beware of insertions as noted above.
Mark