4 ms·
I use Lua a lot these days and coming from Python, it seems silly that I have to provide my own empty? function since standard Lua doesn't offer any way to get
by bayareaguy 18y ago
I use Lua a lot these days and coming from Python, it seems silly that I have to provide my own
empty? function since standard Lua doesn't offer any way to get the
number of elements in an arbitrary table other than to iterate over it:
function empty_p(t)
for k,v in pairs(t) do
return true
end
return false
end
-- later on
if not empty_p(t) then
do_processing(t)
end
This is because although Lua offers a #t operator, it's only
guaranteed to be correct if you're careful about how the table is
constructed. That and the weird ipairs() behavior for non-trivial
tables drives me crazy sometimes. Here's an example:
Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio
> t = {1,2,3}
> print(#t)
3
> for i,v in ipairs(t) do print(i,v) end
1 1
2 2
3 3
Ok so all is good. But now what happens when the table contains a nil?
> t = {1,nil,3}
> print(#t)
3
> for i,v in ipairs(t) do print(i,v) end
1 1
ipairs() stops at the first nil value even though Lua knows there is
data past it. Things get more interesting for tables with non-integer
keys:
> t = {}
> t['a'] = 1
> t['b'] = 2
> print(#t)
0
> t[1] = 1
> print(#t)
1
> for i,v in ipairs(t) do print(i,v) end
1 1
What's going on here is each Lua table has an array for integer valued
keys and a separate hash table for non-integer keys and # and ipairs()
only operate on the first array. To process all the keys you use
pairs():
> for k,v in pairs(t) do print(k,v) end
1 1
a 1
b 2
While at first this doesn't seem to be such a big issue, it's easy to
forget when it's safe to use the #t construct. I've made this error
so often that now whenever my Lua code doesn't do what I expect the
first thing I look for are places where I have something like:
if #t > 0 then
do_processing(t)
end
or
for i,v in ipairs(t)
process(v)
end
because chances are the real problem will turn out to be the particular way I initialized the table.
- silentbicycle 18y agoI suspect this is because a table may be used for an object (or some other abstract data type) which has a different data type. Adding another metatable hook for __empty might be another solution, though. (I agree it's a bit annoying.) > Ok so all is good. But now what happens when the table contains a nil? One of the invariants for the way Lua tables are implemented is that they won't contain nil as a value, IIRC. Using a multifaceted table type for both arrays and dicts is a mixed blessing. It is really convenient much of the time, but it does lead to some quirks. NB: The i in "ipairs" means "integer (keyed) pairs".