From: ara.t.howard@... Date: 2006-08-08T23:50:30+09:00 Subject: Re: Info on continuations / callcc? On Tue, 8 Aug 2006, vasudevram wrote: > > Hi, > > I am Googling and will do more, found some stuff, but interested to get > viewpoints of list members on: > > Continuations in Ruby / the callcc keyword. > > Saw a few URLs which had some info, some of which I understood. But > like I said, personal viewpoints are good to have. > > Thanks > Vasudev > ------------------------------------------------------------------------------------------------------------------------- > Software consulting and training > http://www.dancingbison.com > PDF conversion toolkit: http://sourceforge.net/projects/xtopdf (stable > version 1.0, supports > plain text and DBF conversions to PDF) > ------------------------------------------------------------------------------------------------------------------------- here's some code that uses it to impliment external iterators in ruby, may be helpful: module Enumerable class Iterator public attr_reader :enumerable, :has_next def initialize enumerable, meth = 'each', end_value = nil, &end_block @enumerable = enumerable @meth = meth @end_value = end_value @end_block = end_block initialize_fetch_block end def next ret = @has_next ? fetch_next_element : fetch_end_value (ret.nil? ? ret : (ret.size == 1 ? ret.first : ret)) end def rewind initialize_fetch_block self end protected def initialize_fetch_block callcc do |@after_fetch| @has_next = true @enumerable.send(@meth) 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 def iterator(*a, &b); Iterator::new(self, *a, &b); end class << self def each(*enumerables, &block) iterators = enumerables.collect{|e| e.iterator} while true args = iterators.collect{|i| i.next} if args.detect{|arg| arg} block.call *args else return enumerables end end end def collect(*enumerables, &block) ret = [] each(*enumerables){|*args| ret << (block.call *args)} ret end alias map collect def enumerate(enumerables, meth = 'each', *a, &b) rets = [] iterators = enumerables.map{|e| e.iterator(*a, &b)} iterators.each_with_index do |iterator, idx| rets[idx] << iterator.next end rets end end end if $0 == __FILE__ #{{{ a = ['fee','fie','foe','fum'] h = {'k' => 'v', 'K' => 'V'} ai = a.iterator hi = h.iterator while ((n = ai.next)) do puts n.inspect end while ((n = hi.next)) do puts n.inspect end Enumerable::each a, h do |elem, kv| puts elem.inspect puts kv.inspect end p Enumerable::collect(a,h){|e,kv| [e,kv]} #}}} end __END__ OUTPUT: "fee" "fie" "foe" "fum" ["K", "V"] ["k", "v"] "fee" ["K", "V"] "fie" ["k", "v"] "foe" nil "fum" nil [["fee", ["K", "V"]], ["fie", ["k", "v"]], ["foe", nil], ["fum", nil]] -a -- to foster inner awareness, introspection, and reasoning is more efficient than meditation and prayer. - h.h. the 14th dali lama