From: Ross Bamford Date: 2006-03-24T22:49:41+09:00 Subject: Re: iterator class not working On Fri, 2006-03-24 at 21:38 +0900, Peter Ertl wrote: > Hi, > > in order to understand ruby better (and for fun reasons of course) I try to > write an iterator class. this way I want to understand 'binding' and > 'callcc' better. Here is a slightly modified version of your code that doesn't cover everything, but should get you going in the right direction. ##### code ##### class Iterator def initialize(enum) @yield = lambda do enum.each do |item| @yield = callcc { |cc| @next.call cc, item } end raise "Exhausted" end end def next @yield, item = callcc do |cc| @next = cc @yield.call end item end end names = %w{mary gordy john jane elwood} it = Iterator.new(names) 6.times do puts it.next end ##### outputs ##### mary gordy john jane elwood -:9:in `initialize': Exhausted (RuntimeError) from -:16:in `next' from -:14:in `next' from -:27 from -:26 All you need to bear in mind when using continuations this way is that what you're effectively needing is to 'emulate' two call stacks on a single thread (maybe your 'next' stack and your 'yield' stack) and to chop between them by calling the appropriate continuation. In some respects it's similar to having two threads in a synchronized stop/start setup, which is another way you can implement the above. In fact... http://www.rubyquiz.com/quiz66.html I'll leave the details (proper end handling and so on) to you. Btw, I know this doesn't use binding but I found that to be a fairly unintuitive way to do it. The binding use in your original code was fine in itself I think, but you can't use it to retain state the way I think you were hoping for. -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk