<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Looping Backwards in Ruby</title>
	<atom:link href="http://www.railsrocket.com/looping-backwards-in-ruby/feed" rel="self" type="application/rss+xml" />
	<link>http://www.railsrocket.com/looping-backwards-in-ruby</link>
	<description>A Ruby on Rails community website with tutorials</description>
	<lastBuildDate>Thu, 25 Mar 2010 23:45:08 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: Luis Esteban</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-1211</link>
		<dc:creator>Luis Esteban</dc:creator>
		<pubDate>Sat, 28 Mar 2009 00:17:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-1211</guid>
		<description>&quot;What is the “right” way to iterate through a Range in Ruby backwards?&quot;!

It is nice to do (for the forwards):

(1..10).each{&#124;i&#124; puts &quot;i=#{i}&quot; }

but I don&#039;t like to do (for the backwards):

(1..10).to_a.reverse.each{&#124;i&#124; puts &quot;i=#{i}&quot; }

Well, I don&#039;t actually mind doing that too much, but when I am teaching going backwards, I want to show my students a nice symmetry (i.e. with minimal difference, e.g. only adding a reverse, or a step -1, but without modifying anything else). You can do (for symmetry):

(a=*1..10).each{&#124;i&#124; puts &quot;i=#{i}&quot; }
and
(a=*1..10).reverse.each{&#124;i&#124; puts &quot;i=#{i}&quot; }
which I don&#039;t like much, but you can&#039;t do

(*1..10).each{&#124;i&#124; puts &quot;i=#{i}&quot; } 
(*1..10).reverse.each{&#124;i&#124; puts &quot;i=#{i}&quot; }
#
(1..10).step(1){&#124;i&#124; puts &quot;i=#{i}&quot; }
(1..10).step(-1){&#124;i&#124; puts &quot;i=#{i}&quot; }
#
(1..10).each{&#124;i&#124; puts &quot;i=#{i}&quot; }
(10..1).each{&#124;i&#124; puts &quot;i=#{i}&quot; }   # I don&#039;t want this though.  It&#039;s dangerous

You could ultimately do

class Range
  def each_reverse(&amp;block)
    self.to_a.reverse.each(&amp;block)
  end
end

but I want to teach pure Ruby rather than object oriented approaches (just yet). I would like to iterate backwards:

 - without creating an array (consider 0..1000000000) 
 - working for any Range (e.g. Strings, not just Integers) 
 - without using any extra object oriented power (i.e. no class modification) 

I believe this is impossible without defining a pred method, which means modifying the Range class to use it. If you can do this please let me know, otherwise confirmation of impossibility would be appreciated though it would be disappointing. Perhaps Ruby 1.9 addresses this.

The “right” way is


class Range
  
  def each_reverse(&amp;block)
    i = self.last
    while self === i
      block.call(i)
      i = i.pred
    end
    self
  end
  
  def every(&amp;block)
    if self.first &lt; self.last
      range = self
      direction = :succ
    else
      range = self.last .. self.first
      direction = :pred
    end
    i = self.first
    while range === i
      block.call(i)
      i = i.send(direction)
    end
    self
  end
  
end

class Integer
  
  def pred
    self - 1
  end
  
end

class String
  
  def pred
    return &#039;&#039; if self == &#039;&#039;
    self[0..-2] + (self[-1]-1).chr
  end
  
end




ranges = [
  1..10,
  &#039;a&#039;..&#039;j&#039;,
  10..1,
  &#039;j&#039;..&#039;a&#039;
]

ranges.each do &#124;range&#124;
  puts &quot;#{range.inspect}.each ...&quot;
  range.each{&#124;i&#124; puts i}
  puts &quot;#{range.inspect}.each_reverse ...&quot;
  range.each_reverse{&#124;i&#124; puts i}
  puts &quot;#{range.inspect}.every ...&quot;
  range.every{&#124;i&#124; puts i}
end




(Thanks for your time in reading this.)</description>
		<content:encoded><![CDATA[<p>&#8220;What is the “right” way to iterate through a Range in Ruby backwards?&#8221;!</p>
<p>It is nice to do (for the forwards):</p>
<p>(1..10).each{|i| puts &#8220;i=#{i}&#8221; }</p>
<p>but I don&#8217;t like to do (for the backwards):</p>
<p>(1..10).to_a.reverse.each{|i| puts &#8220;i=#{i}&#8221; }</p>
<p>Well, I don&#8217;t actually mind doing that too much, but when I am teaching going backwards, I want to show my students a nice symmetry (i.e. with minimal difference, e.g. only adding a reverse, or a step -1, but without modifying anything else). You can do (for symmetry):</p>
<p>(a=*1..10).each{|i| puts &#8220;i=#{i}&#8221; }<br />
and<br />
(a=*1..10).reverse.each{|i| puts &#8220;i=#{i}&#8221; }<br />
which I don&#8217;t like much, but you can&#8217;t do</p>
<p>(*1..10).each{|i| puts &#8220;i=#{i}&#8221; }<br />
(*1..10).reverse.each{|i| puts &#8220;i=#{i}&#8221; }<br />
#<br />
(1..10).step(1){|i| puts &#8220;i=#{i}&#8221; }<br />
(1..10).step(-1){|i| puts &#8220;i=#{i}&#8221; }<br />
#<br />
(1..10).each{|i| puts &#8220;i=#{i}&#8221; }<br />
(10..1).each{|i| puts &#8220;i=#{i}&#8221; }   # I don&#8217;t want this though.  It&#8217;s dangerous</p>
<p>You could ultimately do</p>
<p>class Range<br />
  def each_reverse(&amp;block)<br />
    self.to_a.reverse.each(&amp;block)<br />
  end<br />
end</p>
<p>but I want to teach pure Ruby rather than object oriented approaches (just yet). I would like to iterate backwards:</p>
<p> &#8211; without creating an array (consider 0..1000000000)<br />
 &#8211; working for any Range (e.g. Strings, not just Integers)<br />
 &#8211; without using any extra object oriented power (i.e. no class modification) </p>
<p>I believe this is impossible without defining a pred method, which means modifying the Range class to use it. If you can do this please let me know, otherwise confirmation of impossibility would be appreciated though it would be disappointing. Perhaps Ruby 1.9 addresses this.</p>
<p>The “right” way is</p>
<p>class Range</p>
<p>  def each_reverse(&amp;block)<br />
    i = self.last<br />
    while self === i<br />
      block.call(i)<br />
      i = i.pred<br />
    end<br />
    self<br />
  end</p>
<p>  def every(&amp;block)<br />
    if self.first &lt; self.last<br />
      range = self<br />
      direction = :succ<br />
    else<br />
      range = self.last .. self.first<br />
      direction = :pred<br />
    end<br />
    i = self.first<br />
    while range === i<br />
      block.call(i)<br />
      i = i.send(direction)<br />
    end<br />
    self<br />
  end</p>
<p>end</p>
<p>class Integer</p>
<p>  def pred<br />
    self &#8211; 1<br />
  end</p>
<p>end</p>
<p>class String</p>
<p>  def pred<br />
    return &#8221; if self == &#8221;<br />
    self[0..-2] + (self[-1]-1).chr<br />
  end</p>
<p>end</p>
<p>ranges = [<br />
  1..10,<br />
  'a'..'j',<br />
  10..1,<br />
  'j'..'a'<br />
]</p>
<p>ranges.each do |range|<br />
  puts &#8220;#{range.inspect}.each &#8230;&#8221;<br />
  range.each{|i| puts i}<br />
  puts &#8220;#{range.inspect}.each_reverse &#8230;&#8221;<br />
  range.each_reverse{|i| puts i}<br />
  puts &#8220;#{range.inspect}.every &#8230;&#8221;<br />
  range.every{|i| puts i}<br />
end</p>
<p>(Thanks for your time in reading this.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Don Park</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-498</link>
		<dc:creator>Don Park</dc:creator>
		<pubDate>Sun, 04 Jan 2009 05:18:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-498</guid>
		<description>array.reverse.each {&#124;index&#124; ... }</description>
		<content:encoded><![CDATA[<p>array.reverse.each {|index| &#8230; }</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ashes999</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-265</link>
		<dc:creator>ashes999</dc:creator>
		<pubDate>Thu, 20 Nov 2008 16:33:08 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-265</guid>
		<description>I actually don&#039;t need to iterate backwards explicitly; the min/max method works for me. Still, it&#039;s good to know the solution, in case it matters someday.

Cheers!</description>
		<content:encoded><![CDATA[<p>I actually don&#8217;t need to iterate backwards explicitly; the min/max method works for me. Still, it&#8217;s good to know the solution, in case it matters someday.</p>
<p>Cheers!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Wayne Conrad</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-262</link>
		<dc:creator>Wayne Conrad</dc:creator>
		<pubDate>Thu, 20 Nov 2008 14:58:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-262</guid>
		<description>If you needed an iterator that didn&#039;t care which direction you were iterating, you could always make one.  Here&#039;s one clumsy way to do it.  There&#039;s probably a way built into Ruby 1.9, for all I know.

class Range
  def iter(&amp;block)
    if first &lt;= last
      each(&amp;block)
    else
      first.downto(last, &amp;block)
    end
  end
end

(1..5).iter do &#124;i&#124;
  puts(i)
end

(5..1).iter do &#124;i&#124;
  puts(i)
end</description>
		<content:encoded><![CDATA[<p>If you needed an iterator that didn&#8217;t care which direction you were iterating, you could always make one.  Here&#8217;s one clumsy way to do it.  There&#8217;s probably a way built into Ruby 1.9, for all I know.</p>
<p>class Range<br />
  def iter(&amp;block)<br />
    if first &lt;= last<br />
      each(&amp;block)<br />
    else<br />
      first.downto(last, &amp;block)<br />
    end<br />
  end<br />
end</p>
<p>(1..5).iter do |i|<br />
  puts(i)<br />
end</p>
<p>(5..1).iter do |i|<br />
  puts(i)<br />
end</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ashes999</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-250</link>
		<dc:creator>ashes999</dc:creator>
		<pubDate>Wed, 19 Nov 2008 21:36:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-250</guid>
		<description>Wow. That just blows my mind. I knew Ruby had to have some sort of solution for it...

Thanks! The min/max makes my life easier :) but as for the iterating, I still need to use a general solution, because I don&#039;t know if x is less than or more than y.</description>
		<content:encoded><![CDATA[<p>Wow. That just blows my mind. I knew Ruby had to have some sort of solution for it&#8230;</p>
<p>Thanks! The min/max makes my life easier :) but as for the iterating, I still need to use a general solution, because I don&#8217;t know if x is less than or more than y.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Wayne Conrad</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-249</link>
		<dc:creator>Wayne Conrad</dc:creator>
		<pubDate>Wed, 19 Nov 2008 21:07:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-249</guid>
		<description>Oh, I forgot to mention, and you&#039;ll be glad to know I&#039;m sure, that the min and max functions are there, cleverly hidden in Enumerable.  Try [1, 2].max and [1, 2].min for example.</description>
		<content:encoded><![CDATA[<p>Oh, I forgot to mention, and you&#8217;ll be glad to know I&#8217;m sure, that the min and max functions are there, cleverly hidden in Enumerable.  Try [1, 2].max and [1, 2].min for example.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Wayne Conrad</title>
		<link>http://www.railsrocket.com/looping-backwards-in-ruby/comment-page-1#comment-248</link>
		<dc:creator>Wayne Conrad</dc:creator>
		<pubDate>Wed, 19 Nov 2008 20:53:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.railsrocket.com/articles/?p=207#comment-248</guid>
		<description>5.downto(1) do &#124;i&#124;
  puts i
end</description>
		<content:encoded><![CDATA[<p>5.downto(1) do |i|<br />
  puts i<br />
end</p>
]]></content:encoded>
	</item>
</channel>
</rss>

