From: Paul Brannan Date: 2002-11-15T08:01:58+09:00 Subject: Re: Array#next - Enumerable#next ? On Fri, Nov 15, 2002 at 05:40:58AM +0900, ahoward wrote: > class Array > def next > # start iterating if we never have before > @itr = 0 unless @itr > @itr = @itr.succ > > # if there are no more elements return nil > # but also set itr back to zero so subsequent > # calls to next will succeed > if @itr > size > @itr = 0 > return nil > end > > return self[@itr - 1] > end > end One problem here is that I can't tell the difference between iterating over a nil object in an array (e.g. if I have an array [1, 2, 3, nil, 4]) and hitting the end of the array. This is pretty easy to fix; change: return nil to: return DoneIterating A more serious problem here is that code that uses next() is not reentrant; if you have a method that is iterating over an array, you'd better not call another method that also iterates over that array. E.g.: def print_array(arr) while (obj = arr.next) != DoneIterating do puts obj end end def print_all_ocurrances(arr, x) while (obj = arr.next) != DoneIterating do if x == obj then print "Found object x in array " print_array arr puts end end end does not work as expected. To work around this, you should instantiate an iterator object whenever you want to iterate over your array. rubycollections has an iterator library for doing this generically: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/rubycollections/rubycollections/rbc/iterator/ You can use it like this: arr = [1, 2, 3, 4, 5] it = GenericIterator.new(arr) while not it.finished? do p it.elem it.advance end though I regret that I haven't had time to work on this project as much as I would like (one idea that was proposed was to merge my iterators with Horste Duchene's streams, but that's a big project). You might also want to look at: http://www.rubygarden.org/article.php?sid=107 http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/rough/lib/generator.rb?rev=1.6&content-type=text/x-cvsweb-markup http://www.ruby-lang.org/en/raa-list.rhtml?name=stream.rb for some alternate implementations. Paul