Internal iterators in ruby

Hello, the following code can iterate over any number of arrays and has
both the each and collect method implemented. You find some example
usage at the end of the code.
Greetings,
Geert Fannes.

#begin code
class GZipExc < Exception
  def initialize(problem="")
    @ExcStr||="A GZipExc occured"
    super(problem)
  end
end

class GZip
  include Enumerable

  def initialize(*arg)
    raise GZipExc.new("You cannot pass a block to GZip.new. Maybe you
forgot .each or something.") if block_given?
    @arrays=Array.new
    @minLength=nil
    if TrueClass===arg.first
      arg.shift
      arg.each do |a|
        a=a.dup if @arrays.include?(a)
        @arrays.push(a)
        if @minLength
          @minLength=a.length if a.length<@minLength
        else
          @minLength=a.length
        end
      end
    else
      arg.each do |a|
        a=a.dup if @arrays.include?(a)
        @arrays.push(a)
        if @minLength
          raise GZipExc.new("Different lengths found: #{@minLength} !=
#{a.length}.") if a.length!=@minLength
        else
          @minLength=a.length
        end
      end
    end
  end

  def GZip.minLen(*arg)
    new(true,*arg)
  end

  def each
    (0...@minLength).each {|i| yield(@arrays.collect {|a| a[i]})}
  end

  def each_with_index
    (0...@minLength).each {|i| yield((@arrays.collect {|a| a[i]}) << i)}
  end

  def all?
    bOK=true
    (0...@minLength).each do |i|
      if !yield(@arrays.collect {|a| a[i]})
        bOK=false
        break
      end
    end
    return bOK
  end

  def delete_if
    ix=0
    (0...@minLength).each do |i|
      if yield(@arrays.collect {|a| a[ix]})
        @arrays.each{|a| a.delete_at(ix)}
      else
        ix+=1
      end
    end
    return self
  end
end

if $0==__FILE__
  a=[1,2,3]
  b=[4,5,6]
  c=[7,8,9]
  GZip.new(a,b,c).each do |aa,bb,cc|
    print aa,bb,cc,"\n"
  end
  b.push(7)
  begin
    GZip.new(a,b).each do |aa,bb|
      print aa,bb,"\n"
    end
  rescue GZipExc
    puts "I rescued the exception"
  else
    puts "ERROR::i did not catch the expected exception"
  end
  GZip.minLen(a,b).each do |aa,bb|
    print aa,bb,"\n"
  end
  b.pop
  d=GZip.new(a,b,c).collect do |aa,bb,cc|
    [aa,bb,cc]
  end
  d.each do |dd|
    puts dd.join(' ')
  end
end
#end code

···

-----Original Message-----
From: Navya Amerineni [mailto:navyaamerineni@yahoo.com]
Sent: 02 June 2005 05:39
To: ruby-talk ML
Subject: internal iterators in ruby

Hi,

I read that it is difficult to iterate over two
collections in paralell using ruby's internal
iterators.
can any one explain me indetail why it is so..

thanks in advance

Navya

__________________________________
Discover Yahoo!
Get on-the-go sports scores, stock quotes, news and more. Check it out!
http://discover.yahoo.com/mobile.html

Geert Fannes wrote:

Hello, the following code can iterate over any number of arrays and
has both the each and collect method implemented. You find some
example usage at the end of the code.
Greetings,
Geert Fannes.

<snip long code/>

You code works only for arrays, but it's quite efficient.

This works for all Enumerable types, is less efficient - and it's part of
the std lib:

http://www.ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/SyncEnumerator.html

Know your standard libs... :slight_smile:

Kind regards

    robert