Home > Net >  How to idiomatically support closing values with pairs()?
How to idiomatically support closing values with pairs()?

Time:01-30

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.

  • Related