BlaztOne
BlaztOne

Reputation: 180

The "for" loop suddenly be infinite after changing the order of variables

I just recognized that the order of the returned variables does affect how the "for" loop work, which is a pretty interesting thing

local function FakeIpairs(t) --The factory
  local i = i or 0 --The control variable
  
  local function Iterator() --The iterator function
    i = i + 1 --Increment the control variable 
    v = t[i]
      return v, i
  end 
  
  return Iterator
end 
arr = {1, 9, 8, [5] = 10} 
for v, i in FakeIpairs(arr) do 
  print(v)
end 
--[[ 1
     9
     8 --]]

I changed the order of the variable and this happens

local function FakeIpairs(t) --The factory
  local i = i or 0 --The control variable
  
  local function Iterator() --The iterator function
    i = i + 1 --Increment the control variable 
    v = t[i]
      return i, v --[[CHANGED HERE]]
  end 
  
  return Iterator
end 
arr = {1, 9, 8, [5] = 10} 
for i, v --[[AND HERE]] in FakeIpairs(arr) do 
  print(i)
end 
--[[ 1
     9
     8
     nil
     10
     nil
     nil
     nil...--]]

It became an infinite loop immediately without any conditional statement (I put a conditional statement into the function and it worked fine).

What is the relationship between the for loop and the order of returned variables? Why the code would keep return v, i and incrementing i forever if I changed v, i into i, v?

Upvotes: 0

Views: 61

Answers (1)

Olaf Dietsche
Olaf Dietsche

Reputation: 74078

This is explained in the reference manual The generic for loop

The first of these variables is the control variable.

and later on

If the control variable becomes nil, the loop terminates. Otherwise, the body is executed and the loop goes to the next iteration.

In the second example, the first variable is the index (the control variable). The index is incremented at each iteration and never becomes nil. And when the control variable never becomes nil, the loop never stops.

Upvotes: 4

Related Questions