# Unexpected behavior of range.each (Newbie extreme)

**URL:** <https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995>\
**Category:** Ruby\
**Created:** [March 12, 2006, 12:41am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995 "2006-03-12T00:41:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 12:41am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/1 "2006-03-12T00:41:15Z")

</div>

with r=(5…9), r.each{|num| print num,"\n"} behaves as expected.

However if i set r=(9…5) the same method does not behave as though it  
were taking “each” element of the range. It just terminates. Not only  
that but r.include?(7) is false???

Is this a bug or was it done on purpose for some reason? Are range  
specifications only allowed to be “low to high” if so, why? Also if  
so, then why no error message and why does r = (9…5)?

Thanks in advance!  
joe

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 1:13am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/2 "2006-03-12T01:13:51Z")

</div>

On Mar 11, 2006, at 6:53 PM, Tim H. wrote:

> It was done on purpose. Ranges want to be able to iterate from  
> beginning to end using the .succ method on the objects that the  
> range is constructed from. That’s not possible for (9…5). Also,  
> the definition for .include? is range.start \<= val \<= range.end.  
> Not true for (9…5).

There have been several threads over the last few months  
regarding the peculiarities of Ranges. The semantics seem  
a bit confused. Sometimes ranges behave like generated sequences  
of objects, sometimes they behave like intervals, and sometimes  
they just behave like a coordinate pair. The behavior also depends  
quite a bit on the objects used to construct the range.

They are quite convenient in any number of situations but they  
have some rough edges. Is it worth trying to craft an RCR that  
smooths things out a bit?

Gary W.

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 12:55am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/3 "2006-03-12T00:55:43Z")

</div>

Joe P. wrote:

> Thanks in advance!  
> joe

It was done on purpose. Ranges want to be able to iterate from beginning  
to end using the .succ method on the objects that the range is  
constructed from. That’s not possible for (9…5). Also, the definition  
for .include? is range.start \<= val \<= range.end. Not true for (9…5).

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 1:24am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/4 "2006-03-12T01:24:53Z")

</div>

Timothy H. wrote:

> Joe P. wrote:
> 
> > Thanks in advance!  
> > joe
> 
> It was done on purpose. Ranges want to be able to iterate from beginning  
> to end using the .succ method on the objects that the range is  
> constructed from. That’s not possible for (9…5). Also, the definition  
> for .include? is range.start \<= val \<= range.end. Not true for (9…5).

seems like an odd definition of “include” (and “each”) and inconsistent  
with the behavior for arrays. Also, if (9…5) is not a valid range  
specification why no error message?  
It seems to me that the definition of include (and each) for a range  
could be made a bit more tollerant of direction by making it conditional  
on the order of the endpoints. Ahh…Well… guess I ought to stop  
complaining and just go back to learning the language 🙂

Thanks for the explanation!  
joe

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 8:30am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/5 "2006-03-12T08:30:37Z")

</div>

Joe P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> seems like an odd definition of “include” (and “each”) and inconsistent  
> with the behavior for arrays. Also, if (9…5) is not a valid range  
> specification why no error message?

You can’t error on construction simply because end \< start. Consider:

str[2…-1]

> It seems to me that the definition of include (and each) for a range  
> could be made a bit more tollerant of direction by making it conditional  
> on the order of the endpoints. Ahh…Well… guess I ought to stop  
> complaining and just go back to learning the language 🙂

You could make Ranges go backwards, but that changes the soul of the  
ruby Range. (Confusion and code breakage everywhere.) I think having  
backwards ranges do nothing can also have its uses, though I can’t  
conjure up a convincing one on the spot.

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [March 12, 2006, 1:35am UTC](https://www.ruby-forum.com/t/unexpected-behavior-of-range-each-newbie-extreme/79995/6 "2006-03-12T01:35:03Z")

</div>

Hey Joe (Whatcha doin’ with that gun in your hand? – a little Jimi  
Hendrix for you)

Someone might have a better answer than me, but I’ll give it a shot.

The answer to your question is yes, this is intended behavior. Let’s  
look at the Ruby documentation for Range#each:

“Iterates over the elements rng, passing each in turn to the block. You  
can only iterate if the start object of the range supports the succ  
method (which means that you can’t iterate over ranges of Float  
objects).”, [class Range - RDoc Documentation](http://www.ruby-doc.org/core/classes/Range.html#M001156)

Basically, when r = (9…5), you’re first saying: 9#succ, which returns  
10. 10’s outside of your Range which tells #each to stop.

So, yes: “low to high”. I’m not sure, however, why there’s no error  
message.

I hope you found this helpful.

James
