Array#next - Enumerable#next ? 
Author Message
 Array#next - Enumerable#next ?

rubyists-

does anyone know a way to implement this generically for all enumerable
objects in an efficient manner?

  class Array
    def next
      # start iterating if we never have before


      # if there are no more elements return nil
      # but also set itr back to zero so subsequent
      # calls to next will succeed


        return nil
      end


    end
  end

this is really usefull.  if it could be done for any Enumerable object then
something like this :

  module Kernel
    def concert(*enumerables, &block)
      args = enumerable.collect{|e| e.next}
      return if args.include? nil
      block.call *args
    end
  end

  h = {:answer => 42}
  a = [42]

  concert(h, a) do |k,v,a|
    puts k, v, a
  end

would be *very* cool.  also, this could be more generic than some of the
methods being suggested for things like this...

-a

--

 ====================================
 | Ara Howard
 | NOAA Forecast Systems Laboratory
 | Information and Technology Services
 | Data Systems Group
 | R/FST 325 Broadway
 | Boulder, CO 80305-3328

 | Phone:  303-497-7238
 | Fax:    303-497-7259
 ====================================



Tue, 03 May 2005 04:15:27 GMT  
 Array#next - Enumerable#next ?

Quote:

>   class Array
>     def next
>       # start iterating if we never have before


>       # if there are no more elements return nil
>       # but also set itr back to zero so subsequent
>       # calls to next will succeed


>    return nil
>       end


>     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/rubyco...

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?re...
  http://www.ruby-lang.org/en/raa-list.rhtml?name=stream.rb

for some alternate implementations.

Paul



Tue, 03 May 2005 07:01:58 GMT  
 Array#next - Enumerable#next ?

Quote:

> 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

[snip]

yes.  this is a good idea

[snip]

Quote:
> 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

[snip]

i don't view this as a problem - you are viewing the next method as an
iterator, which in definitively is not.  it is an instance method of Array,
and uses instance variables.  i would define Array#next as the the next
object the Array is willing to give me.  this relies on instance variables,
just like Array#size.  if you call a method manipulating Array#size, from
another method manipulating Array#size - would you be suprised that size had
changed?  this is good argument for iterator classes i suppose : one needs a
separte object for tracking state.  however, i've been using that method quite
a bit - it's usefull because it's minimal.

i will check out the links you sent.  thanks.

-a

--

 ====================================
 | Ara Howard
 | NOAA Forecast Systems Laboratory
 | Information and Technology Services
 | Data Systems Group
 | R/FST 325 Broadway
 | Boulder, CO 80305-3328

 | Phone:  303-497-7238
 | Fax:    303-497-7259
 ====================================



Tue, 03 May 2005 09:22:42 GMT  
 Array#next - Enumerable#next ?

Quote:
> i don't view this as a problem - you are viewing the next method as an
> iterator, which in definitively is not.  it is an instance method of Array,
> and uses instance variables.  i would define Array#next as the the next
> object the Array is willing to give me.

It puts the state of an iteration over the array inside the array,
which is evil, even if looks convenient. Traps:

- Iteration within another iteration.
- Iteration from different threads.
- Aborting an iteration early and then starting it again without
  resetting the iteration state.

Quote:
> if you call a method manipulating Array#size, from another method
> manipulating Array#size - would you be suprised that size had
> changed?

No, because I'm changing the array. But in the above I'm not changing
the array, only iterate over it. In other words it turns a non-destructive
operation of iterating over the array into a destructive operation which
modifies the array.

--
  __("<      Marcin Kowalczyk

   ^^    http://qrnik.knm.org.pl/~qrczak/



Thu, 05 May 2005 18:22:41 GMT  
 Array#next - Enumerable#next ?
Kinda old question, but anyway -- does anyone have any luck in
installing and running mod_ruby and eruby on MacOS X 10.2? On my system
httpd reports a bunch of unresolved ruby symbols, such as rb_cObject
and others.

Thank you,
Gennady.



Fri, 06 May 2005 14:35:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Next vs. Access.fliename.Next()

2. NeXT/NeXT STEP Oberon?

3. call-next-next-method

4. how can i put the next file in array

5. Next generation virtual OS written in Smalltalk

6. Java really *is* the next version of Visual Basic

7. APL display postscript font for NeXT

8. Possible Catenation Bug In J 5.0 for the NeXT

9. Next APL Conference: APL92 6-10 July 1992 St. Petersburg, Russia

10. J for the NeXT

11. Can't compile v6.2 on the NeXT

12. Dolphin and DotNet in next version?

 

 
Powered by phpBB® Forum Software