views:

90

answers:

1

I have a very simple little piece of Lua code, which I wrote while teaching myself how coroutines work.

I was fine until I got to coroutine.wrap, the spec states:

coroutine.wrap (f)

Creates a new coroutine, with body f. f must be a Lua function. Returns a function that resumes the coroutine each time it is called. Any arguments passed to the function behave as the extra arguments to resume. Returns the same values returned by resume, except the first boolean. In case of error, propagates the error.

However this code:

Enumeration = {}

Enumeration.Create = function(generator)
    return coroutine.wrap(generator, coroutine.yield)
end

local function TestEnumerator(yield)
    yield(1) --ERROR HERE
    yield(2)
    yield(3)
end

local enumerator = Enumeration.Create(TestEnumerator)
local first = enumerator()
local second = enumerator()
local third = enumerator()

print (first, second, third)

Complains that yield is nil (on the line I have marked above). As I understand it, yield should be the second argument passed into coroutine.wrap, so where am I going wrong?

Really obvious solution, thanks to the answer below

Enumeration.Create = function(generator)
    local iter = coroutine.wrap(generator, coroutine.yield)
    return function()
        return iter(coroutine.yield)
    end
end
+3  A: 

This is not how coroutine.wrap works. You have to pass coroutine.yield in the first call to enumerator.

lhf
Bah, once you said that it becamse so obvious I was simply misreading the documentation.
Martin
To get a more uniform behaviour you need cooperation of the wrapped functions but if they yield as soon as they start then Create can wrap and call it once to set yield.
lhf