Alexander Kellett wrote:
> On Tue, Aug 10, 2004 at 03:46:17PM +0900, Robert Klemme wrote:
> 
>>Hm, sounds to me like it was not general enough to include it in
>>Enumerable.  Before I see that method I'd prefer to have size and empty?
>>in Enumerable.  Just my 0.02 EUR...
> 
> 
> personally the idea of having a method taking 4 procs
> in the stdlib is just a bit strange. i'd prefer to see
> a generic set of methods that are somehow mixedin to
> the values that a Enumerable yields, therefore allowing
> things like val.last? or first? or even a generic 
> val.enum_index to replace the each_with_index rubbish.
> i've no idea how to solve this neatly unfortunately as
> extend'ing the objects that are yield'ed of course will
> have sideeffects... though most of the side effects that
> will cause problems shouldn't happen at all, e.g people
> calling is_a? a lot will have problems... i do this 
> and yet i don't have an exception to such an extension...
> but this:
>    
>    blah.each { 
>       |element| 
>       pos = blah.index element
>       puts blah[pos-1]
>       puts element
>    }
> 
> is soooooo uggllyyy... not to mention inefficient...
> i'd just loooveeee to see a element.previous_in_enum...

Why not something like this (each_with_first_last does not exist!):

   blah.each_with_first_last {|element, pos|
     case pos
     when :inside # or middle
       ...
     when :first
       ...
     when :last
       ...
     end
   }

Of course this would be somewhat slower than the approach with 4 procs, 
as you have to test where you are, inside the loop. If you use the 
approach above, make sure that you test for the common-case ("inside") 
in the case-statement at the very beginning.

I know, you could also use each_with_index instead (this one exists!):

   blah.each_with_index {|element, inx|
     if inx == 0
       # first
     elsif inx < blah.size
       # inside
     else
       # last
     end
   }

But that might not work for all Enumerable's.

Or maybe, an extended each_with_index2?:

blah.each_with_index2 {|element, inx, pos|
   if pos == :first
   ...
}

Regards,

   Michael