# Bizarre Range behavior

**URL:** <https://rubytalk.org/t/bizarre-range-behavior/54751>\
**Category:** ruby-talk\
**Created:** [4 August 2009 18:47 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751 "2009-08-04T18:47:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Scott\_Briggs](https://avatars.discourse-cdn.com/v4/letter/s/8e7dd6/32.png) [@Scott\_Briggs](https://rubytalk.org/u/Scott_Briggs)\
**Post date:** [4 August 2009 18:47 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/1 "2009-08-04T18:47:05Z")

</div>

Can someone please explain this behavior in ruby (1.8.6p111):

> > ("2"..."8").to\_a

=\> ["2", "3", "4", "5", "6", "7"]

> > ("2".."8").to\_a

=\> ["2", "3", "4", "5", "6", "7", "8"]

> > ("2".."9").to\_a

=\> ["2", "3", "4", "5", "6", "7", "8", "9"]

> > ("2".."10").to\_a

=\>

> > ("2".."11").to\_a

=\>

> > ("1".."11").to\_a

=\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]

Cheers,  
Scott

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Yossef\_Mendelssohn](https://avatars.discourse-cdn.com/v4/letter/y/f19dbf/32.png) [@Yossef\_Mendelssohn](https://rubytalk.org/u/Yossef_Mendelssohn)\
**Post date:** [4 August 2009 19:04 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/2 "2009-08-04T19:04:57Z")

</div>

> Can someone please explain this behavior in ruby (1.8.6p111):
> 
> \>\> ("2"..."8").to\_a
> 
> =\> ["2", "3", "4", "5", "6", "7"]\>\> ("2".."8").to\_a
> 
> =\> ["2", "3", "4", "5", "6", "7", "8"]\>\> ("2".."9").to\_a
> 
> =\> ["2", "3", "4", "5", "6", "7", "8", "9"]\>\> ("2".."10").to\_a  
> =\>   
> \>\> ("2".."11").to\_a  
> =\>   
> \>\> ("1".."11").to\_a
> 
> =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]

It gets better.

&nbsp;&nbsp;&nbsp;&nbsp;\>\> ("100".."11").to\_a  
&nbsp;&nbsp;&nbsp;&nbsp;=\> ["100"]

It seems you're running not so much into strange Range behavior as  
strange String behavior in certain numeric circumstances. Or maybe a  
combination of strange Range and String behvior. If you want the  
ranges to make more sense, use actual numbers.

&nbsp;&nbsp;&nbsp;&nbsp;\>\> (2..11).to\_a  
&nbsp;&nbsp;&nbsp;&nbsp;=\> [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

If you want strings in the result, you can get that with a little bit  
of work.

&nbsp;&nbsp;&nbsp;&nbsp;\>\> (2..11).to\_a.map { |x| x.to\_s }  
&nbsp;&nbsp;&nbsp;&nbsp;=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]

> **···**
>
> On Aug 4, 1:47 pm, Scott Briggs \<scott...@gmail.com\> wrote:
> 
> --  
> -yossef

---

<div class="post-metadata">

**Author:** ![Matt\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matt\_Williams](https://rubytalk.org/u/Matt_Williams)\
**Post date:** [4 August 2009 19:15 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/3 "2009-08-04T19:15:04Z")

</div>

It's because you're using strings -- "11" comes before "2", hence the failure, because it's an invalid range, just as if you had (11 .. 2) is invalid.

Matt

> **···**
>
> On Wed, 5 Aug 2009, Scott Briggs wrote:
> 
> > Can someone please explain this behavior in ruby (1.8.6p111):
> > 
> > > > ("2"..."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7"]
> > 
> > > > ("2".."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8"]
> > 
> > > > ("2".."9").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9"]
> > 
> > > > ("2".."10").to\_a
> > 
> > =\>
> > 
> > > > ("2".."11").to\_a
> > 
> > =\>
> > 
> > > > ("1".."11").to\_a
> > 
> > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]

---

<div class="post-metadata">

**Author:** ![Scott\_Briggs](https://avatars.discourse-cdn.com/v4/letter/s/8e7dd6/32.png) [@Scott\_Briggs](https://rubytalk.org/u/Scott_Briggs)\
**Post date:** [4 August 2009 19:26 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/4 "2009-08-04T19:26:52Z")

</div>

Matt, that doesn't explain why "1".."11" works and "2".."11" doesn't  
work.

Scott

Matthew K. Williams wrote:

> **···**
>
> > On Wed, 5 Aug 2009, Scott Briggs wrote:
> > 
> > > > > ("2".."11").to\_a
> > > 
> > > =\>
> > > 
> > > > > ("1".."11").to\_a
> > > 
> > > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
> > 
> > It's because you're using strings -- "11" comes before "2", hence the  
> > failure, because it's an invalid range, just as if you had (11 .. 2) is  
> > invalid.
> > 
> > Matt
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [4 August 2009 19:38 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/5 "2009-08-04T19:38:33Z")

</div>

> > Can someone please explain this behavior in ruby (1.8.6p111):
> > 
> > > > ("2"..."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7"]\>\> ("2".."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8"]\>\> ("2".."9").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9"]\>\> ("2".."10").to\_a  
> > =\>
> > 
> > > > ("2".."11").to\_a
> > 
> > =\>
> > 
> > > > ("1".."11").to\_a
> > 
> > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]

Well, you need to think about String#succ when the Range endpoints are String.

> It gets better.
> 
> > > ("100".."11").to\_a
> 
> &nbsp;&nbsp;&nbsp;=\> ["100"]

Now, that one is odd. I'd have predicted a result of:  
&nbsp;&nbsp;=\> ["100", "101", "102", "103", "104", "105", "106", "107", "108", "109"]  
on the basis of staring with "100" and applying #succ until the value was \>"11" like this loop does:

a =   
v = "100"  
loop do  
&nbsp;&nbsp;&nbsp;break if v \> "11"  
&nbsp;&nbsp;&nbsp;a \<\< v  
&nbsp;&nbsp;&nbsp;v = v.succ  
end  
p a

This loop produced the "right" result for "2".."11" (namely an empty array) so the actual result defies (my) explanation.

> It seems you're running not so much into strange Range behavior as  
> strange String behavior in certain numeric circumstances. Or maybe a  
> combination of strange Range and String behvior. If you want the  
> ranges to make more sense, use actual numbers.
> 
> > > (2..11).to\_a
> 
> &nbsp;&nbsp;&nbsp;=\> [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
> 
> If you want strings in the result, you can get that with a little bit  
> of work.
> 
> > > (2..11).to\_a.map { |x| x.to\_s }
> 
> &nbsp;&nbsp;&nbsp;=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
> 
> --  
> -yossef

Of course, you can also do things like:

("a".."ah").to\_a  
=\> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah"]

Which might help label your spreadsheet columns.

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Aug 4, 2009, at 3:04 PM, Yossef Mendelssohn wrote:
> 
> > On Aug 4, 1:47 pm, Scott Briggs \<scott...@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [4 August 2009 19:42 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/6 "2009-08-04T19:42:53Z")

</div>

> Can someone please explain this behavior in ruby (1.8.6p111):
> 
> > > > ("2"..."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7"]
> > 
> > > > ("2".."8").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8"]
> > 
> > > > ("2".."9").to\_a
> > 
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9"]
> > 
> > > > ("2".."10").to\_a
> > 
> > =\>
> > 
> > > > ("2".."11").to\_a
> > 
> > =\>
> > 
> > > > ("1".."11").to\_a
> > 
> > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
> 
> It's because you're using strings -- "11" comes before "2", hence the failure, because it's an invalid range, just as if you had (11 .. 2) is invalid.
> 
> Matt

Well, it certainly isn't invalid. You can easily have a Range where the end is less than the begin value.

r = 3..-1  
=\> 3..-1

> r.to\_a

=\>

> "hello"[r]

=\> "lo"

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Aug 4, 2009, at 3:15 PM, Matthew K. Williams wrote:
> 
> > On Wed, 5 Aug 2009, Scott Briggs wrote:

---

<div class="post-metadata">

**Author:** ![Scott\_Briggs](https://avatars.discourse-cdn.com/v4/letter/s/8e7dd6/32.png) [@Scott\_Briggs](https://rubytalk.org/u/Scott_Briggs)\
**Post date:** [4 August 2009 19:29 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/7 "2009-08-04T19:29:24Z")

</div>

Ah, I should clarify that. When ruby interprets "11" as an integer 11  
for "1".."11", then why doesn't it do the same when it's "2".."11"?

Scott

Scott Briggs wrote:

> **···**
>
> > Matt, that doesn't explain why "1".."11" works and "2".."11" doesn't  
> > work.
> > 
> > Scott
> > 
> > Matthew K. Williams wrote:
> > 
> > > On Wed, 5 Aug 2009, Scott Briggs wrote:
> > > 
> > > > > > ("2".."11").to\_a
> > > > 
> > > > =\>
> > > > 
> > > > > > ("1".."11").to\_a
> > > > 
> > > > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
> > > 
> > > It's because you're using strings -- "11" comes before "2", hence the  
> > > failure, because it's an invalid range, just as if you had (11 .. 2) is  
> > > invalid.
> > > 
> > > Matt
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Matt\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matt\_Williams](https://rubytalk.org/u/Matt_Williams)\
**Post date:** [4 August 2009 19:40 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/8 "2009-08-04T19:40:10Z")

</div>

> Matt, that doesn't explain why "1".."11" works and "2".."11" doesn't  
> work.

irb(main):015:0\> "1" \< "11"  
=\> true  
irb(main):016:0\> "2" \< "11"  
=\> false

irb(main):021:0\> "11" \< "2"  
=\> true

This is true because it's comparing strings to get the range -- it compares the first character of each string, then stops when it can't go any further.

Try this for an example of how the expansion is occurring:

("a".."cat".to\_a

(I'm only putting a portion of it here)

=\> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "aa", "ab",  
....  
"caa", "cab", "cac", "cad", "cae", "caf", "cag", "cah", "cai", "caj", "cak", "cal", "cam", "can", "cao", "cap", "caq", "car", "cas", "cat"]

In string order, it's going to compare strings of length 1 first, then strings of length 2, etc... Here's another example (with an attempt at an explanation):

irb(main):019:0\> ("11" .. "2").to\_a  
=\> ["11"]

As we've seen before, "11" \< "2", so it's a part of the range, but then it stops, we're done.

Matt

> **···**
>
> On Wed, 5 Aug 2009, Scott Briggs wrote:
> 
> > Scott
> > 
> > Matthew K. Williams wrote:
> > 
> > > On Wed, 5 Aug 2009, Scott Briggs wrote:
> > > 
> > > > > > ("2".."11").to\_a
> > > > 
> > > > =\>
> > > > 
> > > > > > ("1".."11").to\_a
> > > > 
> > > > =\> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
> > > 
> > > It's because you're using strings -- "11" comes before "2", hence the  
> > > failure, because it's an invalid range, just as if you had (11 .. 2) is  
> > > invalid.
> > > 
> > > Matt
> > 
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Matt\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matt\_Williams](https://rubytalk.org/u/Matt_Williams)\
**Post date:** [4 August 2009 19:45 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/9 "2009-08-04T19:45:56Z")

</div>

It's doing a comparison of the strings -- it has to do with the length of the string. "100" is longer than "11", it also happens to be less characters (and, based on #succ, it's "less").

In order to find the range, it's going to compare the two strings --

+ it compares for the string lengths to get whether the beginning is less than the end

+ It then uses #succ to try to expand the range, but since "100" has more characters than "11", it stops...

Hope I've not muddied it too much.....

Matt

> **···**
>
> On Wed, 5 Aug 2009, Rob Biedenharn wrote:
> 
> > > It gets better.
> > > 
> > > > > ("100".."11").to\_a
> > > 
> > > &nbsp;&nbsp;&nbsp;=\> ["100"]
> > 
> > Now, that one is odd. I'd have predicted a result of:  
> > =\> ["100", "101", "102", "103", "104", "105", "106", "107", "108", "109"]  
> > on the basis of staring with "100" and applying #succ until the value was
> > 
> > > "11" like this loop does:

---

<div class="post-metadata">

**Author:** ![Matt\_Williams](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matt\_Williams](https://rubytalk.org/u/Matt_Williams)\
**Post date:** [4 August 2009 20:04 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/10 "2009-08-04T20:04:39Z")

</div>

I guess the code for substring treats it differently than #to\_a -- just taking the bounds. Huh. That's pretty interesting. Learn something every day. Makes sense when I stop to think about it, though.

Just don't try "hello"[3,-1]....

I need to read the rdocs more often....  
Matt

> **···**
>
> On Wed, 5 Aug 2009, Rob Biedenharn wrote:
> 
> > Well, it certainly isn't invalid. You can easily have a Range where the end is less than the begin value.
> > 
> > r = 3..-1  
> > =\> 3..-1  
> > \> r.to\_a  
> > =\>   
> > \> "hello"[r]  
> > =\> "lo"

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [4 August 2009 20:32 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/11 "2009-08-04T20:32:37Z")

</div>

> > > It gets better.
> > > 
> > > > > ("100".."11").to\_a
> > > 
> > > &nbsp;&nbsp;=\> ["100"]
> > 
> > Now, that one is odd. I'd have predicted a result of:  
> > =\> ["100", "101", "102", "103", "104", "105", "106", "107", "108", "109"]  
> > on the basis of staring with "100" and applying #succ until the value was
> > 
> > > "11" like this loop does:
> 
> It's doing a comparison of the strings -- it has to do with the length of the string. "100" is longer than "11", it also happens to be less characters (and, based on #succ, it's "less").
> 
> In order to find the range, it's going to compare the two strings --
> 
> + it compares for the string lengths to get whether the beginning is less than the end
> 
> + It then uses #succ to try to expand the range, but since "100" has more characters than "11", it stops...
> 
> Hope I've not muddied it too much.....
> 
> Matt

Well, the Range#to\_a is actually Enumerable#to\_a and uses Range#each defined in range.c

After checking that the beginning of the range responds to :succ and if it is a Fixnum (which are special), it finds that the Range.begin is a String:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (TYPE(beg) == T\_STRING) {  
&nbsp;&nbsp;VALUE args[5];  
&nbsp;&nbsp;long iter[2];

&nbsp;&nbsp;args[0] = beg;  
&nbsp;&nbsp;args[1] = end;  
&nbsp;&nbsp;args[2] = range;  
&nbsp;&nbsp;iter[0] = 1;  
&nbsp;&nbsp;iter[1] = 1;  
&nbsp;&nbsp;rb\_iterate(str\_step, (VALUE)args, step\_i, (VALUE)iter);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

str\_step calls rb\_str\_upto defined in string.c

VALUE  
rb\_str\_upto(VALUE beg, VALUE end, int excl)  
{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE current, after\_end;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ID succ = rb\_intern("succ");  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int n;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringValue(end);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = rb\_str\_cmp(beg, end);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (n \> 0 || (excl && n == 0)) return beg;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;after\_end = rb\_funcall(end, succ, 0, 0);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current = beg;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (!rb\_str\_equal(current, after\_end)) {  
&nbsp;&nbsp;rb\_yield(current);  
&nbsp;&nbsp;if (!excl && rb\_str\_equal(current, end)) break;  
&nbsp;&nbsp;current = rb\_funcall(current, succ, 0, 0);  
&nbsp;&nbsp;StringValue(current);  
&nbsp;&nbsp;if (excl && rb\_str\_equal(current, end)) break;  
&nbsp;&nbsp;StringValue(current);  
&nbsp;&nbsp;if (RSTRING\_LEN(current) \> RSTRING\_LEN(end) || RSTRING\_LEN(current) == 0)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return beg;  
}

Now, not having read a lot of Ruby's C code, I'm not sure what some bits are for (like calling StringValue(current) so much), but it does ultimately behave almost like Matt said. The difference being that the rb\_yield(current) has already happened once before the length check (RSTRING\_LEN(current) \> RSTRING\_LEN(end)). I think the RSTRING\_LEN(current)==0 is there to catch "".succ == "", but that just means that (""..any).to\_a is [""] and yet ("".."").to\_a is (because after\_end will be "" and the loop is never entered).

So it's the odd situation that String is given some special treatment and has the unusual property that there are strings a,b such that:  
a \< b && a.length \> b.length

Knowing this, here's an even more bizzare-looking example:

> "19".succ

=\> "20"

> ("2".."19").to\_a

=\>

> ("2"..."20").to\_a

=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Aug 4, 2009, at 3:45 PM, Matthew K. Williams wrote:
> 
> > On Wed, 5 Aug 2009, Rob Biedenharn wrote:

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [5 August 2009 04:55 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/12 "2009-08-05T04:55:55Z")

</div>

Hi,

> Knowing this, here's an even more bizzare-looking example:
> 
> > "19".succ
> 
> =\> "20"
> 
> > ("2".."19").to\_a
> 
> =\>
> 
> > ("2"..."20").to\_a
> 
> =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> "14", "15", "16", "17", "18", "19"]

What if I sprinkle more magic to the language and change String#upto  
to generate numerical sequences when all characters in edges are  
digits, so that

> ("2".."19").to\_a

=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]

> ("2"..."20").to\_a

=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"]

Any opinion? I already made a patch for trunk.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matz.

> **···**
>
> In message "Re: Bizarre Range behavior" on Wed, 5 Aug 2009 05:32:37 +0900, Rob Biedenharn \<Rob@AgileConsultingLLC.com\> writes:

---

<div class="post-metadata">

**Author:** ![Daniel\_Berger2](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/daniel_berger2/32/2243_2.png) [@Daniel\_Berger2](https://rubytalk.org/u/Daniel_Berger2)\
**Post date:** [5 August 2009 06:27 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/13 "2009-08-05T06:27:08Z")

</div>

I vote against. If people want numeric ranges, it's their job to use  
numerics, not magically convert stringy numbers into actual numbers. This  
isn't Perl after all.

Regards,

Dan

> **···**
>
> > -----Original Message-----  
> > From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]  
> > Sent: Tuesday, August 04, 2009 10:56 PM  
> > To: ruby-talk ML  
> > Subject: Re: Bizarre Range behavior
> > 
> > Hi,
> > 
> > In message "Re: Bizarre Range behavior" \> on Wed, 5 Aug 2009 05:32:37 +0900, Rob Biedenharn \> \<Rob@AgileConsultingLLC.com\> writes:
> > 
> > \>Knowing this, here's an even more bizzare-looking example:  
> > \>  
> > \>\> "19".succ  
> > \>=\> "20"  
> > \>\> ("2".."19").to\_a  
> > \>=\>   
> > \>\> ("2"..."20").to\_a  
> > \>=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > \>"14", "15", "16", "17", "18", "19"]
> > 
> > What if I sprinkle more magic to the language and change String#upto  
> > to generate numerical sequences when all characters in edges are  
> > digits, so that
> > 
> > \> ("2".."19").to\_a  
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > "14", "15", "16", "17", "18", "19"]  
> > \> ("2"..."20").to\_a  
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > "14", "15", "16", "17", "18", "19", "20"]
> > 
> > Any opinion? I already made a patch for trunk.

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [5 August 2009 11:14 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/14 "2009-08-05T11:14:45Z")

</div>

Yukihiro Matsumoto wrote:

> What if I sprinkle more magic to the language and change String#upto  
> to generate numerical sequences when all characters in edges are  
> digits, so that
> 
> \> ("2".."19").to\_a  
> =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> "14", "15", "16", "17", "18", "19"]  
> \> ("2"..."20").to\_a  
> =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> "14", "15", "16", "17", "18", "19", "20"]
> 
> Any opinion?

-1 for added complexity with little benefit

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [5 August 2009 15:35 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/15 "2009-08-05T15:35:41Z")

</div>

I'd actually prefer \*less\* magic here. (And I hope that your second example with "2"..."20" wouldn't include "20" since the range excludes its end.)

The surprising aspect is that the Range#to\_a can give an array that has just the #begin. String#upto perhaps needs more magic to know that #succ will eventually work ("9".upto("10") as well as "cat".upto("bird"))

-Rob

Rob Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Aug 5, 2009, at 12:55 AM, Yukihiro Matsumoto wrote:
> 
> > Hi,
> > 
> > In message "Re: Bizarre Range behavior" \> on Wed, 5 Aug 2009 05:32:37 +0900, Rob Biedenharn \<Rob@AgileConsultingLLC.com \> \> writes:
> > 
> > \>Knowing this, here's an even more bizzare-looking example:  
> > \>  
> > \>\> "19".succ  
> > \>=\> "20"  
> > \>\> ("2".."19").to\_a  
> > \>=\>   
> > \>\> ("2"..."20").to\_a  
> > \>=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > \>"14", "15", "16", "17", "18", "19"]
> > 
> > What if I sprinkle more magic to the language and change String#upto  
> > to generate numerical sequences when all characters in edges are  
> > digits, so that
> > 
> > \> ("2".."19").to\_a  
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]  
> > \> ("2"..."20").to\_a  
> > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"]
> > 
> > Any opinion? I already made a patch for trunk.
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matz.

---

<div class="post-metadata">

**Author:** ![James\_Coglan2](https://avatars.discourse-cdn.com/v4/letter/j/c67d28/32.png) [@James\_Coglan2](https://rubytalk.org/u/James_Coglan2)\
**Post date:** [5 August 2009 11:44 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/16 "2009-08-05T11:44:21Z")

</div>

I'm also against this. I prefer explicit type conversions here: changing  
behaviour because a string happens to look like a number will likely cause  
more problems than it solves. In fact this kind of thing shows up in  
JavaScript and it usually masks bugs where the developer has failed to  
properly handle user input.

If this change were to go ahead, I'd also argue for changing String#+ to  
recognise numbers, which might also mean changing Numeric#+ for symmetry.

> **···**
>
> 2009/8/5 Brian Candler \<b.candler@pobox.com\>
> 
> > Yukihiro Matsumoto wrote:  
> > \> What if I sprinkle more magic to the language and change String#upto  
> > \> to generate numerical sequences when all characters in edges are  
> > \> digits, so that  
> > \>  
> > \> \> ("2".."19").to\_a  
> > \> =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > \> "14", "15", "16", "17", "18", "19"]  
> > \> \> ("2"..."20").to\_a  
> > \> =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > \> "14", "15", "16", "17", "18", "19", "20"]  
> > \>  
> > \> Any opinion?
> > 
> > -1 for added complexity with little benefit
> 
> --  
> James Coglan  
> [http://jcoglan.com](http://jcoglan.com)

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [5 August 2009 13:08 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/17 "2009-08-05T13:08:44Z")

</div>

I strongly agree. Typing .to\_i isn't too hard and it makes clear what  
is intended.

Kind regards

robert

> **···**
>
> 2009/8/5 Daniel Berger \<djberg96@gmail.com\>:
> 
> > > -----Original Message-----  
> > > From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]  
> > > Sent: Tuesday, August 04, 2009 10:56 PM  
> > > To: ruby-talk ML  
> > > Subject: Re: Bizarre Range behavior
> > > 
> > > Hi,
> > > 
> > > In message "Re: Bizarre Range behavior" \>\> on Wed, 5 Aug 2009 05:32:37 +0900, Rob Biedenharn \>\> \<Rob@AgileConsultingLLC.com\> writes:
> > > 
> > > \>Knowing this, here's an even more bizzare-looking example:  
> > > \>  
> > > \>\> "19".succ  
> > > \>=\> "20"  
> > > \>\> ("2".."19").to\_a  
> > > \>=\>   
> > > \>\> ("2"..."20").to\_a  
> > > \>=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > \>"14", "15", "16", "17", "18", "19"]
> > > 
> > > What if I sprinkle more magic to the language and change String#upto  
> > > to generate numerical sequences when all characters in edges are  
> > > digits, so that
> > > 
> > > \> ("2".."19").to\_a  
> > > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > "14", "15", "16", "17", "18", "19"]  
> > > \> ("2"..."20").to\_a  
> > > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > "14", "15", "16", "17", "18", "19", "20"]
> > > 
> > > Any opinion? I already made a patch for trunk.
> > 
> > I vote against. If people want numeric ranges, it's their job to use  
> > numerics, not magically convert stringy numbers into actual numbers. This  
> > isn't Perl after all.
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [5 August 2009 13:48 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/18 "2009-08-05T13:48:46Z")

</div>

Hi,

> **···**
>
> In message "Re: Bizarre Range behavior" on Wed, 5 Aug 2009 20:14:45 +0900, Brian Candler \<b.candler@pobox.com\> writes:
> 
> > Yukihiro Matsumoto wrote:
> > 
> > > What if I sprinkle more magic to the language and change String#upto  
> > > to generate numerical sequences when all characters in edges are  
> > > digits,
> 
> > -1 for added complexity with little benefit
> 
> I admit it's a dark art of Perl-ish, but String#upto and String#succ  
> that a range of strings calls already have astonishingly Perl-ish  
> complexity (and I don't think we can remove the magic), and I prefer  
> hard-boiled magic to half-cooked current one. Actually, I think this  
> magic is the one I should have invented and added years ago.
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matz.

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [5 August 2009 14:00 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/19 "2009-08-05T14:00:04Z")

</div>

I agree. I'm against the change.

James Edward Gray II

> **···**
>
> On Aug 5, 2009, at 1:27 AM, Daniel Berger wrote:
> 
> > > -----Original Message-----  
> > > From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]  
> > > Sent: Tuesday, August 04, 2009 10:56 PM  
> > > To: ruby-talk ML  
> > > Subject: Re: Bizarre Range behavior
> > > 
> > > Hi,
> > > 
> > > In message "Re: Bizarre Range behavior" \>\> on Wed, 5 Aug 2009 05:32:37 +0900, Rob Biedenharn \>\> \<Rob@AgileConsultingLLC.com\> writes:
> > > 
> > > \>Knowing this, here's an even more bizzare-looking example:  
> > > \>  
> > > \>\> "19".succ  
> > > \>=\> "20"  
> > > \>\> ("2".."19").to\_a  
> > > \>=\>   
> > > \>\> ("2"..."20").to\_a  
> > > \>=\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > \>"14", "15", "16", "17", "18", "19"]
> > > 
> > > What if I sprinkle more magic to the language and change String#upto  
> > > to generate numerical sequences when all characters in edges are  
> > > digits, so that
> > > 
> > > \> ("2".."19").to\_a  
> > > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > "14", "15", "16", "17", "18", "19"]  
> > > \> ("2"..."20").to\_a  
> > > =\> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",  
> > > "14", "15", "16", "17", "18", "19", "20"]
> > > 
> > > Any opinion? I already made a patch for trunk.
> > 
> > I vote against. If people want numeric ranges, it's their job to use  
> > numerics, not magically convert stringy numbers into actual numbers. This isn't Perl after all.

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [5 August 2009 16:12 UTC](https://rubytalk.org/t/bizarre-range-behavior/54751/20 "2009-08-05T16:12:18Z")

</div>

Hi,

> I'd actually prefer \*less\* magic here. (And I hope that your second  
> example with "2"..."20" wouldn't include "20" since the range excludes  
> its end.)

May bad for the error in the example. It wouldn't include "20" in the  
actual code.

> The surprising aspect is that the Range#to\_a can give an array that  
> has just the #begin. String#upto perhaps needs more magic to know that  
> #succ will eventually work ("9".upto("10") as well as  
> "cat".upto("bird"))

We have to define the "magic" behavior first, but I love magic if we  
can make specific definition.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matz.

> **···**
>
> In message "Re: Bizarre Range behavior" on Thu, 6 Aug 2009 00:35:41 +0900, Rob Biedenharn \<Rob@AgileConsultingLLC.com\> writes:

[Next page](https://rubytalk.org/t/bizarre-range-behavior/54751.md?page=2)
