Hi mental,


> Maybe think of it like foreach in TCL [ foreach i $things { ... } ],
> or the one for in Javascript [ for (var i in things) { ... } ]
> rather than for in C.

Hmm, I don't know tcl nor JS well enough.

> As a rule, I think Ruby's going to be extremely counterintuitive
> whenever you expect C-like behavior.

It worked quite well before.

> That will probably require thinking about it from a different angle.
>  The "skip the next (future) element based on the current one" is an
> inherently messy concept.

Perhaps more messy than a loop without this feature, but a 

 next_and_skip_next_element

should be perfectly clear to a reader. I mean, if we have
'complicated' constructs such as 'inject', we will be able to cope
with 'skip_next_element', won't we?


[...]

>  prev = nil
>  a.each do |elt|
>    puts elt unless prev == "b"
>    prev = elt
>  end
>
> Now, we'll imagine for the moment that Ruby has C-like for loops:
>
>  a = %w(a b c d e)
>
>  for ( i = 0 ; i < a.size ; i += 1 )
>    puts a[i]
>    i += 1 if a[i] == "b"
>  end

You know that those are not the same. The first one is looking back,
the second could look forward.

> Out of curiousity, do you think either of these would be clearer?
>
>  a.each_with_prev do |elt, prev|
>    next if prev == "b"
>    puts elt
>  end

Definitely, but one can do this already with inject. Well, almost.

> A lot of Ruby's clarity comes not from being able to write things
> clearly in the "raw" language, but from being able to easily
> customize the language for your needs.

Of course, and that is what I am asking in the whole thread! Is there
a nicer way for this loop... Let's see. I have this each_with_next
now, but still I am completely unstatisfied with my loop. But I am now
convinced that I have the optimal solution, even if it the way it
looks now. And btw., I need a look-ahead for this specific purpose.
The each_with_previous was a very nice hint, thanks, even if I wasn't
able to use it. I'd probably have to create each_with_prev_and_next.


module Enumerable
  def each_with_next(last=nil)
    prev=nil
    first=true
    each do |elt|
      begin
        if first
          first=false
          next
        else
          yield prev,elt
        end
      ensure # in case of 'next'
        prev = elt
      end
    end
    yield prev,last
  end
end


a=[:a, :b, :b, :c, :b, :d, :e]

skip=false

a.each_with_next do |elt,n|
  if skip
    skip=false
    next
  end
  if elt==:b && n==:b
    puts "double_b"
    skip=true
  else
    puts elt
  end
end


Patrick

(please, no cc:)