From: Pit Capitain Date: 2001-08-24T19:53:10+09:00 Subject: [ruby-talk:20271] Re: Lazy computation (was: breaking out of nested loops) On 24 Aug 2001, at 7:03, Brian Marick wrote: > At 03:18 AM 8/23/01, you wrote: > >I'd still like to find a way to suspend an arbitrary computation, get > >a "resumer" that can be passed around and called anywhere to return > >the next value. > ( class LazyComputation skipped ) Hi Brian, thanks for the code. I like it. It looks very much like my Iterator class, which I needed to traverse multiple Enumerables in parallel. I wanted to publish it some months ago, but never took the time to actually do so. Now that you've come up independently with a similar structure, it seems that this is the "right" way to interrupt a computation and continue it from the outside. Just in case you're curious here's the Iterator class (the name comes from the Java Iterator interface). class Iterator public attr_reader :enumerable, :has_next def initialize( enumerable, end_value = nil, &end_block ) @enumerable = enumerable @end_value = end_value @end_block = end_block initialize_fetch_block end def next @has_next ? fetch_next_element : fetch_end_value end def rewind initialize_fetch_block self end protected def initialize_fetch_block callcc do | @after_fetch | @has_next = true @enumerable.each do | @next_element | callcc do | @next_fetch | @after_fetch.call end end @has_next = false @next_fetch = nil @after_fetch.call end @after_fetch = nil end def fetch_next_element result = @next_element callcc do | @after_fetch | @next_fetch.call end @after_fetch = nil result end def fetch_end_value @end_block ? @end_block.call : @end_value end end If somebody needs to traverse multiple enumerables in parallel and doesn't want to use matz's solution in the FAQ which uses threads then write me and I'll finally take the time to publish the code. Pit