Forum: Ruby unexpected behavior of range.each (Newbie extreme)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
49c4935f50f26608ba704f29da8e93b4?d=identicon&s=25 Joe Percival (joep)
on 2006-03-12 00:41
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
37a3c73ffbf864e4b28f7f2384ee12ce?d=identicon&s=25 Timothy Hunter (tim-hunter)
on 2006-03-12 00:55
(Received via mailing list)
Joe Percival 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).
9c1018f025d0c39fdf2158f1be358502?d=identicon&s=25 Gary Wright (Guest)
on 2006-03-12 01:13
(Received via mailing list)
On Mar 11, 2006, at 6:53 PM, Tim Hunter 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 Wright
49c4935f50f26608ba704f29da8e93b4?d=identicon&s=25 Joe Percival (joep)
on 2006-03-12 01:24
Timothy Hunter wrote:
> Joe Percival 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
90ebe8da17aabd36cc30d9f96a530e6f?d=identicon&s=25 James H. (Guest)
on 2006-03-12 01:35
(Received via mailing list)
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).", 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
851246810c70dbfcc1815c636b054562?d=identicon&s=25 George Ogata (Guest)
on 2006-03-12 08:30
(Received via mailing list)
Joe Percival <bttman@bigtreestech.com> 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.
This topic is locked and can not be replied to.