lua-users home
lua-l archive

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


Am 02.10.2013 23:35 schröbte Tim Hill:
The sum was purely an example to illustrate the difficulty in
creating a robust API. The issue here is the behavior of # when
arrays have holes are can thus be viewed either as a "array with
holes" or a "array with other integer keys after the end of the
array". # gives odd results in these cases, which means (to my mind)
its risky to use # when an array is not well-formed.
Yes, it is, so don't use it. There is a Lua API that provides stricter 
guarantees than `#`: `ipairs()`. You will always get a proper sequence 
and the problem of holes just vanishes, and what remains is the problem 
of determining if the table has the expected number of elements. If you 
write life-or-death software, you probably want to validate each array 
element anyway, the number of elements in the array is a small problem 
compared to that.
So: If you have an expected number of elements (`n`) use a numeric for 
loop from 1 to n, and the matter of holes in the array just disappears 
during type checking. If you don't have an exact expected number of 
elements, use `ipairs()` for type checking and do the number-of-elements 
check at the end. You can transform case 2 into case 1 by letting your 
API-users specify the number of elements *they* think the array should 
have as an extra parameter.
After type-checking you should always keep track of the array-length 
using a variable or a table-field.
And thus I find it desirable to check to see if an array is well-formed before using # .. but there is no way to do this in Lua that is not O(n).

If this were all my code base, then, as others have suggested, the solution is "make sure you don't create ill-formed arrays", but it's NOT all my code base and I need to be defensive when writing APIs to be consumed by others.

--Tim

Philipp


TL;DR: I see no point in checking the sequence status of a table without checking that it doesn't contain arbitrary booleans/threads/strings/tables/userdata, etc. The later also requires O(n), and the usable sequence length then comes for free.