From: Luke Graham Date: 2005-03-11T22:58:44+09:00 Subject: Re: Is iterating in lock-step possible? Just found this, it seems to fit the bill nicely and its in the std lib of all places :P http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/Generator.html On Fri, 11 Mar 2005 23:44:39 +1000, Luke Graham wrote: > Gah, always miss something when I post code... > > Replace the first two lines of nextco with > def nextco > each_with_index { |e,i| > > > On Fri, 11 Mar 2005 23:41:46 +1000, Luke Graham wrote: > > On Fri, 11 Mar 2005 15:57:08 +0900, Roshan James wrote: > > > > > I was trying to write code where I can have two or more computations > > > which generate values that I need to compare - with the ruby syntax > > > tying iterator usage to the code blocks by syntax, there is no way I can > > > do this. This is especially applicable when the iterators potentially > > > return an infinite stream of values. (Except for using contiuations... > > > Which is not really so much of a solution, because I might as well not > > > have used an iterator in a first place if I could create good > > > coroutines) > > > > Continuations are the right answer in this case. > > > > module Enumerable > > attr_accessor :co, :st, :res > > > > def nextco > > each { |e| > > callcc { |cc| > > @co = cc > > @res = e > > @st.call > > } > > } > > @res = nil > > @st.call > > end > > def next > > callcc { |cc| > > @st = cc > > @co ? @co.call : nextco > > } > > return @res > > end > > end > > > > a = [1,2,3] > > b = [4,5,6,7,8] > > > > while x = a.next and y = b.next > > puts x,y > > end > > > > Note there are three possible behaviours around the @res = nil > > line. One is to return nil after all items have been used up, another > > is to keep returning the last item by removing that line, and finally > > a loop can be wrapped around the each, to begin returning from > > the first item again. > > > > Its probably possible to do it in one function, but it makes more > > sense to me in two. > > > > > Yes I understand that I take a hit (wrt perf by choosing ruby), but > > > that's a BAD argument to favour wrapping state first by a iterators and > > > then once over by a continuation. > > > > As long as its wrapped safely and nicely, what does it matter? > > This way, you even get your choice of what to do when you > > run out of items ;) > > > > -- > > spooq > > > > -- > spooq > -- spooq