On Fri, Aug 13, 2010 at 12:34 PM, Greg Ewing email@example.com wrote:
Are you perhaps confusing the value produced by 'yield' with the function return value of a cofunction or a generator used with yield-from? They're different things, and it's the return value that gets seen by the function doing the cocall or yield-from. That's what enables you to think you're writing in a normal imperative style.
I'll admit that I was forgetting the difference between the return value of yield and that of yield from. So send() isn't essential.
def sock_readline(sock): buf = "" while buf[-1:] != "\n": block_for_reading(sock) yield data = sock.recv(1024) if not data: break buf += data if not buf: close_fd(sock) return buf
The 'yield' in there is what suspends the coroutine, and it neither sends or receives any value. The data read from the socket is returned to the caller by the return statement at the end. [Clarification: block_for_reading doesn't actually suspend, it just puts the current coroutine on a list to be woken up when the socket is ready.]
But the "yield" is also the point that allows the scheduler to throw in an exception to indicate that the socket has gone away and that the error should be propagated up the coroutine stack.
You need throw() at least to participate in proper exception handling.