🎓 A1Learner
🔍
0 of 52 lessons completed

Lua Coroutines with Wrap

coroutine.wrap is a function that turns a coroutine body into a plain function. Calling that function resumes the coroutine and returns its yielded values directly.

Wrap turns a coroutine into a plain function

The wrap function yields 10 and then 20. Calls take both values, and a check shows the final call returns nothing.

local next_value = coroutine.wrap(function()
  coroutine.yield(10)
  coroutine.yield(20)
end)
local a = next_value()
print(a)
local b = next_value()
print(b)
local c = next_value()
print(c == nil)

A wrap function works as a generic for iterator

The body yields multiples of 5. The generic for loop takes each value until the body ends.

local iter = coroutine.wrap(function()
  for i = 1, 3 do
    coroutine.yield(i * 5)
  end
end)
for value in iter do
  print(value)
end

Wrap raises a body error instead of returning false

A pcall around the wrap call catches the raised error. The check shows the message ends with the word boom.

local boom = coroutine.wrap(function()
  error("boom")
end)
local ok, err = pcall(boom)
print(ok, err:sub(-4) == "boom")

Example

local next_word = coroutine.wrap(function()
  for i, word in ipairs({"red", "green", "blue"}) do
    coroutine.yield(word)
  end
end)
for word in next_word do
  print(word)
end
local ok, err = pcall(next_word)
print(ok, err)

Key points

  • Wrap: coroutine.wrap returns a function that resumes the coroutine when called.
  • Call: each call returns the next value the body yields.
  • Finish: the call that lets the body finish returns the body return value or nothing.
  • After: a later call raises an error because the coroutine is dead.
  • Generic for: a wrap function can serve as the iterator in a generic for loop.

In this example, the wrap function yields each word in turn for the generic for loop. The loop stops when the body finishes and returns nothing. A later call fails because the coroutine is dead.

Note

wrap gives no coroutine value, so it gives no status to check.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does coroutine.wrap do when the body fails?