An implementation I have done in the past converts the following:
for x, y, z in input do
print(x, y, z)
end
into:
local _iterator = input
local _invariant, _control
if type(input) == "table" then
local _mt = getmetatable(input)
if type(_mt) == "table" and type(_mt.__iter) == "function" then
_iterator, _invariant, _control = _mt.__iter(input)
else
_iterator, _invariant, _control = pairs(input) -- !
end
end
for x, y, z in _iterator, _invariant, _control do
print(x, y, z)
end
This may not be 100% correct but could be a good starting point.
As it can't be determined statically whether the subject of iteration is (1) a plain table, (2) an iterator function, or (3) a table with an __iter metamethod defined, it is necessary to insert a runtime check.
Notes:
Using pairs(input) does not necessarily conform to the order of Luau generic iteration (for example, consecutive array indices starting from 1 go first)
Doesn't handle iterating over userdata (with __iter defined), which is supported by Luau
There may also be issues with accessing __iter if __metatable is set
See https://github.com/seaofvoices/darklua/issues/202 for motivation.
An implementation I have done in the past converts the following:
into:
This may not be 100% correct but could be a good starting point.
As it can't be determined statically whether the subject of iteration is (1) a plain table, (2) an iterator function, or (3) a table with an
__iter
metamethod defined, it is necessary to insert a runtime check.Notes:
pairs(input)
does not necessarily conform to the order of Luau generic iteration (for example, consecutive array indices starting from 1 go first)__iter
defined), which is supported by Luau__iter
if__metatable
is set