heres another one. it also defines an iterator class:
----CUT----
module Enumerable
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
enumerable instance methods
def iterator; @iterator = Iterator.new self; end
enumerables class methods
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
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]]
----CUT----
-a
···
On Wed, 8 Oct 2003, quent wrote:
zoranlazarevic@yahoo.com (Zoran Lazarevic) wrote in message news:32c0bb6a.0310071950.55c75dd0@posting.google.com…
Apparently it is not possible to iterate using Collection.each over
multiple collections. It is possible by using one thread per
collection, but I do not want to go there.
a continuations multi_each has been placed on the wiki at rubygarden.org
if you are interested
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
The difference between art and science is that science is what we understand
well enough to explain to a computer. Art is everything else.
– Donald Knuth, “Discover”
~ > /bin/sh -c ‘for lang in ruby perl; do $lang -e “print "\x3a\x2d\x29\x0a"”; done’
====================================