lua-users home
lua-l archive

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


I'm utterly puzzled by the behavior of this fragment:

local alphanumsort = function(o)
    table.sort(o, function(a,b)
print('---', a, b) for k,v in ipairs(o) do print(k,v) end
      return (o[a] or 9)..a < (o[b] or 9)..b
    end) end
alphanumsort({1,2,3,4,5,6,7,'a',1.2,-1})

This is a simplified fragment from an application I have been working
on. On my machine (Windows with Lua 5.1.4) it dies with:

sort.pl:4: attempt to concatenate local 'b' (a nil value)
stack traceback:
	sort.pl:4: in function <sort.pl:2>
	[C]: in function 'sort'
	sort.pl:2: in function 'alphanumsort'
	sort.pl:6: in main chunk
	[C]: ?

Where does this "nil" value come from? It is clearly not in the
original table. if I replace ..a and ..b with tostring(a) and
tostring(b), I get "invalid order function for sorting", which usually
indicates that the function returns inconsistent results (1 < 5 in one
case and 1 > 5 in another), but I don't see why it would do it in this
case. Basically, the idea is to sort elements that match their
positions first and sort everything else after that.

Even more puzzling, when I replace "o[a] or 9" with "o[a] and 0 or 9",
things start working as expected, but maybe it just hides the issue;
not sure.

If you review the output, you notice that some elements got swapped
even though I would not expect them to be (that may be a red herring
though as they get swapped in "normal" cases too). For example, values
for 5 and 9 get swapped, even though 5 is "before" 1.2 given the
result of the comparator.

---	-1	5
1	1
2	2
3	3
4	4
5	5
6	6
7	7
8	a
9	1.2
10	-1
---	2	5
1	1
2	2
3	3
4	4
5	1.2
6	6
7	7
8	a
9	5
10	-1

Paul.