# Puzzling behaviour with range

**URL:** <https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125>\
**Category:** Ruby\
**Created:** [January 7, 2009, 5:09pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125 "2009-01-07T17:09:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 5:09pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/1 "2009-01-07T17:09:46Z")

</div>

Hi all!

I’ve been over (some of) the documentation, and I can’t figure this one  
out, can anyone tell me what range is expecting? And, why it’s behavior  
is different from other numerics?

$ ruby -v  
ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]  
$ irb  
irb(main):001:0\> 1.class  
=\> Fixnum  
irb(main):002:0\> 3.14.class  
=\> Float  
irb(main):003:0\> 1…4.class  
ArgumentError: bad value for range  
from (irb):3  
from :0  
irb(main):004:0\> (1…4).class  
=\> Range  
irb(main):005:0\>

Thanks!

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 5:14pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/2 "2009-01-07T17:14:48Z")

</div>

Alle Wednesday 07 January 2009, Raphael C. ha scritto:

> =\> Fixnum  
> Thanks!  
> The point is that 1…4.class is parsed as 1…(4.class), that is  
> 1…Fixnum  
> which, of course, isn’t a valid range.

Stefano

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 5:17pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/3 "2009-01-07T17:17:11Z")

</div>

Raphael C. wrote:

> Hi all!
> 
> I’ve been over (some of) the documentation, and I can’t figure this one  
> out, can anyone tell me what range is expecting?

Two values that are comparable to each other.  
1…4 works because 1 and 4 can be compared.  
1…4.class does not work because 1 and Integer are not comparable to  
each  
other.

> And, why it’s behavior  
> is different from other numerics?

a) Range is not a numeric  
b) Which difference do you mean?

HTH,  
Sebastian

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 6:14pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/4 "2009-01-07T18:14:26Z")

</div>

> Of course, in typing this out, I see why it’s set up the way it is,  
> Thanks for setting me on the path! (and letting me babble on…)  
> Well it all comes down to the principle of least surprise in the end,  
> and I think that it is properly set up to fit within the principle. Even  
> though none of us wants to put parenthesis … anywere really.

Andy C…

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 6:08pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/5 "2009-01-07T18:08:06Z")

</div>

Sebastian H. wrote:

> a) Range is not a numeric  
> b) Which difference do you mean?
> 
> HTH,  
> Sebastian

Thanks for the reply!

I guess what I’m getting at is that the Ruby parser makes a lot of  
assumptions, when I write something like 1.class, the parser assumes I’m  
calling a method on the Fixnum 1 rather than assuming I’m trying to make  
some strange Float. And when I type 3.14.class the parser is again smart  
enough to figure things out, but this behavior is not carried over to  
range. I know it’s a design choice, and that range needs to be able to  
hold more than just numerics, but since a statement like “range 1…‘d’”  
is meaningless, it seems like the proper behavior for range should be to  
examine the first element of the range statement and then assume the  
second element is of the same type (at least as far as parsing method  
calls goes) then we would have (x…y).class == x…y.class which seems  
like it would be more in line with other basic data types…

Of course, in typing this out, I see why it’s set up the way it is,  
since we might want to do something like this…

class SomeObj  
def lastOne()  
17  
end  
end  
blah = SomeObj::new  
a = 1…blah.lastOne

Thanks for setting me on the path! (and letting me babble on…)

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 7, 2009, 11:16pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/6 "2009-01-07T23:16:14Z")

</div>

On 07.01.2009 18:07, Raphael C. wrote:

> assumptions, when I write something like 1.class, the parser assumes I’m  
> calling a method on the Fixnum 1 rather than assuming I’m trying to make  
> some strange Float.

What you call “assumptions” is actually “precedence”. The syntax of the  
language is defined as it is and “.” (method invocation, not to be  
confused with the decimal point) has higher precedence than the range  
operator “…”. This really makes sense, for example:

for i in s.min…s.max  
puts i  
end

> And when I type 3.14.class the parser is again smart  
> enough to figure things out, but this behavior is not carried over to  
> range. I know it’s a design choice, and that range needs to be able to  
> hold more than just numerics, but since a statement like “range 1…‘d’”  
> is meaningless, it seems like the proper behavior for range should be to  
> examine the first element of the range statement and then assume the  
> second element is of the same type (at least as far as parsing method  
> calls goes) then we would have (x…y).class == x…y.class which seems  
> like it would be more in line with other basic data types…

It cannot work that way because of the way parsers work: first the lexer  
recognizes tokens. This is where it needs to decide that “1.23” is a  
float literal and “1.23.class” is actually three literals (“1.23”, “.”,  
“class”). Only after that phase that parser builds up the parse tree  
which also establishes precedence. Your suggestion basically requires  
to define different productions in the syntax for ranges with integer  
literals and for ranges with other expressions to the left and right of  
“…”. I am not sure whether this is actually possible but there is a  
certain risk that the syntax will not be conflict free and in any way it  
means making the beast even more complex than it is today. Given the  
limited usability and the easy workaround I’d say that cost estimates  
rule against this change.

> Of course, in typing this out, I see why it’s set up the way it is,  
> since we might want to do something like this…
> 
> class SomeObj  
> def lastOne()  
> 17  
> end  
> end  
> blah = SomeObj::new  
> a = 1…blah.lastOne

Exactly, arbitrary expressions are allowed on both sides of the “…”.  
Note also, that in this case the type of expression is actually unknown  
at parse time.

> Thanks for setting me on the path! (and letting me babble on…)

🙂

Cheers

robert

---

<div class="post-metadata">

**Author:** ![puffer\_ape](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/58f4c7/32.png) [@puffer\_ape](https://www.ruby-forum.com/u/puffer_ape)\
**Post date:** [January 8, 2009, 12:30pm UTC](https://www.ruby-forum.com/t/puzzling-behaviour-with-range/157125/7 "2009-01-08T12:30:39Z")

</div>

Andy C. wrote:

> Even  
> though none of us wants to put parenthesis … anywere really.

Well, at least one of us likes parentheses.

If you see something like (3.14).class you don’t have to stop and think  
about it. But 3.14.class makes one mentally come to a screeching halt,  
back up, do a double-take, and then get out the Pickaxe book to look up  
the precedence rules. Or fire up irb and suck-it-and-see. 😉

I prefer clarity over saving a couple of keystrokes!

Dave
