I'm new to Lua (language version 5.4 if it matters, there doesn't seem to be a tag for that version on SO yet) and I'm trying to find the most idiomatic way to implement iteration (for
loop) over a userdata object.
The Lua 5.4 Reference Manual says regarding a loop statement for var_1, ···, var_n in explist do body end
:
The loop starts by evaluating explist to produce four values: an iterator function, a state, an initial value for the control variable, and a closing value.
The idiomatic way to loop seems to be using the pairs(t)
function. This also works for userdata via the __pairs
metamethod. However:
If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call.
Why only three instead of four? If I have a complex userdata object that needs to allocate some resource for a loop, I'll need that closing value so I know when to deallocate that resource in case the loop ends early, right? Does that mean I cannot use pairs
in such a case or am I missing something?
I could of course provide a new function, say pairs4
, but that doesn't seem to be very idiomatic.
CodePudding user response:
Because that's how it has always worked since at least Lua 5.0. pairs
always returned 3 values because for
previously only took 3 values.
"to-be-closed variables" are a new feature of Lua 5.4, as is the fourth value for generic for
. Why pairs
wasn't updated to match is unknown. It is possible that pairs
returns all of the values from the __pairs
metamethod, but I haven't looked at the implementation to verify this.
In this case, I would suggest writing a pairs_close
that returns 4 arguments from the __pairs
metamethod.