"Berger, Daniel" <Daniel.Berger / qwest.com> schrieb im Newsbeitrag
news:8FE83020B9E1A248A182A9B0A7B76E7358B379 / itomae2km07.AD.QINTRA.COM...
> > -----Original Message-----
> > From: pmak / aaanime.net [mailto:pmak / aaanime.net]
> > Sent: Wednesday, March 30, 2005 11:30 AM
> > To: ruby-talk ML
> > Subject: Syntax sugar idea for loops
> >
> >
> > I was working with a proprietary programming language called
> > Traction <www.tractionsoftware.com>, and I noticed something
> > pretty cool they had in their loop constructs.
> >
> > Consider the following Ruby code:
> >
> >     every_other = true
> >     people.each do |person|
> >         every_other = !every_other
> >         row_class = every_other ? 'row1' : 'row2'
> >         puts "<tr class=#{row_class}><td>#{person.name}</td>
> > <td>#{person.email}</td></tr>"
> >     end
> >
> > This code prints out an HTML table of peoples' names and
> > e-mail addresses. The <tr> tags alternate with having
> > class="row1" and class="row2", allowing every other row to be
> > colored differently.
> >
> > Consider these two lines of the code, though:
> >
> >     every_other = true
> >         every_other = !every_other
> >
> > These lines could be replaced by syntax sugar. Traction has
> > the following "Special Loop Tags":
> >
> >     <loop.first>: true if this is the first iteration of the loop
> >     <loop.inner> true if this is not the first or last
> > iteration of the loop
> >     <loop.odd> true if this is an odd iteration
> >     <loop.last>: true if this is the last iteration of the loop
> >
> > (In the case of nested loops, they apply to the innermost
> > loop.) Maybe Ruby could use this sort of syntax sugar, too?
> > So in my example above, there would be a built-in variable
> > that replaces my "every_other" variable.
>
> I think Enumerable#each_with_index largely eliminates the need for such
> syntactic sugar.  Consider:
>
> people.each_with_index do |person, i|
>    puts "First person: #{person}" if i == 0
>    row_class = i%2 == 0 ? "row1" : "row2"
>    puts "<tr class=#{row_class}><td>#{person.name}</td>
>    puts "Last person: #{person}" if i == people.length - 1
> end

Yeah, "odd" and "even" are much too specific IMHO.  Using the index is the
most general solution.  That way you can do things like shown above plus:

people.each_with_index do |person, i|
   row_class = "row#{(i%2)+1}"
   puts "<tr class=#{row_class}><td>#{person.name}</td>
end

people.each_with_index do |person, i|
   row_class = case i % 3
     when 0; "rowx"
     when 1; "rowy"
     when 2; "rowz"
   end
   puts "<tr class=#{row_class}><td>#{person.name}</td>
end

ROW_CLASS = ["foo", "bar", "baz"]
....
people.each_with_index do |person, i|
   puts "<tr class=#{ROW_CLASS[i %
ROW_CLASS.size]}><td>#{person.name}</td>
end

The last one being the most efficient one I guess.

Kind regards

    robert