# Newbee Question on what if x === 2..5 does

**URL:** <https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544>\
**Category:** Ruby\
**Created:** [May 4, 2006, 12:51am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544 "2006-05-04T00:51:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 12:51am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/1 "2006-05-04T00:51:06Z")

</div>

I’m new to ruby and don’t understand why the following code does what  
is does. Can anyone enlighten me?

ruby -e 'a = [1,2,3,4,5,6,7,8,9,10]; a.each { |x| if (x === 2…5 )  
then print x, " " end}; puts ’  
2 3 4 5 6 7 8 9 10

I would have thought this would be the same as

ruby -e 'a = [1,2,3,4,5,6,7,8,9,10]; a.each { |x| case x; when 2…5  
then print x, " "; end}; puts ’  
2 3 4 5

I am also confused that

ruby -e ‘while gets; print if /\<div id=.\*$/ … /\</body\>/; end’ \< fred

UETHUEPUK THEUTEUH teuhepxn thueonhoe ononueuouh

and a three . range test give the same output.

ruby -e ‘while gets; print if /\<div id=.\*$/ … /\</body\>/; end’ \< fred

UETHUEPUK THEUTEUH teuhepxn thueonhoe ononueuouh

The original file ‘fred’ is

hello
UETHUEPUK THEUTEUH teuhepxn thueonhoe ononueuouh

ruby -v  
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.6.0]

Compiled from the distribution, not the Mac OS shipped version.

Rob

Rob B. Ph: +64 (9) 3737 599 Extn 87972  
Computing Services Manager Fax: +64 (9) 3737 453  
Computer Science Department Mob:+64 (27) 4731 856  
The University of Auckland  
Rm 391, Level 3  
38 Princes Street [Robs Home Page](http://www.cs.auckland.ac.nz/~rob)  
Private bag 92019 [http://www.wikarekare.org](http://www.wikarekare.org)  
Auckland 1001 [http://www.burrowes.org](http://www.burrowes.org)

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 1:09am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/2 "2006-05-04T01:09:13Z")

</div>

On 5/3/06, Rob B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> then print x, " "; end}; puts ’  
> 2 3 4 5

Try switching x === 2…5 to 2…5 === x. The case equality operator  
(===) is not cummutative. The conditions of a case statement are  
evaluated using the when condition as the _receiver_ of the case  
equality operator, not the argument. Ie.

case a  
when b  
…  
end

is equivalent to:

if b === a  
…  
end

> 

Sorry, can’t help you there. I always have a hard time remembering  
what the difference between … and … are in that context. I stay  
away from it in favor of more descriptive flagging in a while loop.  
E.g.:

flag = false  
while line = gets  
flag = true if line =~ /\<div id=.\*$/  
flag = false if line =~ /\</body\>/  
print line if flag  
end

Jacob F.

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 3:01am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/3 "2006-05-04T03:01:54Z")

</div>

I mistyped that (left out an =), but the same result.

rob1:~ rbur004$ ruby -e ‘a = [1,2,3,4,5,6,7,8,9,10]; a.each { |x|  
print x, “-\>”; if (2…5 === x) then print x, " " end; print “\n”}’  
1-\>  
2-\>  
3-\>  
4-\>  
5-\>  
6-\>  
7-\>  
8-\>  
9-\>  
10-\>

On 4/05/2006, at 12:42 PM, Rob B. wrote:

> 6-\>
> 
> > > what  
> > > 2 3 4 5
> > 
> > > ruby -e 'while gets; print if /
> > > /; end'
> > 
> > Sorry, can’t help you there. I always have a hard time remembering
> 
> 38 Princes Street [Robs Home Page](http://www.cs.auckland.ac.nz/~rob)  
> Private bag 92019 [http://www.wikarekare.org](http://www.wikarekare.org)  
> Auckland 1001 [http://www.burrowes.org](http://www.burrowes.org)

Rob

Rob B. Ph: +64 (9) 3737 599 Extn 87972  
Computing Services Manager Fax: +64 (9) 3737 453  
Computer Science Department Mob:+64 (27) 4731 856  
The University of Auckland  
Rm 391, Level 3  
38 Princes Street [Robs Home Page](http://www.cs.auckland.ac.nz/~rob)  
Private bag 92019 [http://www.wikarekare.org](http://www.wikarekare.org)  
Auckland 1001 [http://www.burrowes.org](http://www.burrowes.org)

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 3:13am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/4 "2006-05-04T03:13:55Z")

</div>

Hmmm, it works if I bracket the range. Why is that?

rob1:~ rbur004$ ruby -e '[1,2,3,4,5,6,7,8,9,10].each { |x| print x, "-

> "; if ((2…5) === x) then print x end; print “\n”}’  
> 1-\>  
> 2-\>2  
> 3-\>3  
> 4-\>4  
> 5-\>  
> 6-\>  
> 7-\>  
> 8-\>  
> 9-\>  
> 10-\>

On 4/05/2006, at 1:00 PM, Rob B. wrote:

> 7-\>
> 
> > print x, “-\>”; if (2…5 == x) then print x, " " end; print “\n”}’
> > 
> > > > 2 3 4 5 6 7 8 9 10  
> > > > equality operator, not the argument. Ie.  
> > > > end  
> > > > ononueuouh  
> > > > teuhepxn  
> > > > flag = false

Rob

Rob B. Ph: +64 (9) 3737 599 Extn 87972  
Computing Services Manager Fax: +64 (9) 3737 453  
Computer Science Department Mob:+64 (27) 4731 856  
The University of Auckland  
Rm 391, Level 3  
38 Princes Street [Robs Home Page](http://www.cs.auckland.ac.nz/~rob)  
Private bag 92019 [http://www.wikarekare.org](http://www.wikarekare.org)  
Auckland 1001 [http://www.burrowes.org](http://www.burrowes.org)

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 2:43am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/5 "2006-05-04T02:43:43Z")

</div>

I get what you mean. It makes sense to have the === as a method of  
the range, not of x, but this produces no result at all.

rob1:~ rbur004$ ruby -e ‘a = [1,2,3,4,5,6,7,8,9,10]; a.each { |x|  
print x, “-\>”; if (2…5 == x) then print x, " " end; print “\n”}’  
1-\>  
2-\>  
3-\>  
4-\>  
5-\>  
6-\>  
7-\>  
8-\>  
9-\>  
10-\>

On 4/05/2006, at 11:06 AM, Jacob F. wrote:

> > ruby -e 'a = [1,2,3,4,5,6,7,8,9,10]; a.each { |x| case x; when 2…5  
> > …  
> > ruby -e ‘while gets; print if /\<div id=.\*$/ … /\</body\>/; end’ \<  
> > and a three . range test give the same output.
> 
> print line if flag  
> end
> 
> Jacob F.

Rob

Rob B. Ph: +64 (9) 3737 599 Extn 87972  
Computing Services Manager Fax: +64 (9) 3737 453  
Computer Science Department Mob:+64 (27) 4731 856  
The University of Auckland  
Rm 391, Level 3  
38 Princes Street [Robs Home Page](http://www.cs.auckland.ac.nz/~rob)  
Private bag 92019 [http://www.wikarekare.org](http://www.wikarekare.org)  
Auckland 1001 [http://www.burrowes.org](http://www.burrowes.org)

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 3:20am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/6 "2006-05-04T03:20:06Z")

</div>

Try using:  
if (2…5) === x

the === seems to bind before the …

;D

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 3:20am UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/7 "2006-05-04T03:20:21Z")

</div>

On May 3, 2006, at 9:13 PM, Rob B. wrote:

> Hmmm, it works if I bracket the range. Why is that?

=== has higher precendence than the … operator

2…5 === x is

2…(5 === x)

without parens

---

<div class="post-metadata">

**Author:** ![robtotheb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@robtotheb](https://www.ruby-forum.com/u/robtotheb)\
**Post date:** [May 4, 2006, 5:49pm UTC](https://www.ruby-forum.com/t/newbee-question-on-what-if-x-2-5-does/59544/8 "2006-05-04T17:49:47Z")

</div>

On 5/3/06, Rob B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hmmm, it works if I bracket the range. Why is that?

I came to the same result as others. I also figured out why you were  
getting that weird behavior when using the if statement. Let’s take a  
simple test: 3 in 2…5? In irb:

> > 2…5 === 3  
> > ArgumentError: bad value for range

> > (2…5) === 3  
> > =\> true

Looks right, 5 === 3 was binding first, so in the first case we really  
had 2…false (since 5 === 3 is false). To verify:

> > 2…false  
> > ArgumentError: bad value for range

So why doesn’t this code:

[1,2,3,4,5,6,7,8,9,10].each do |x|  
puts x if 2…5 === x  
end

raise that exception? If I use select instead, it “works”:

> > [1,2,3,4,5,6,7,8,9,10].select{ |x| 2…5 === x }  
> > ArgumentError: bad value for range

The key is the binding again, let’s look at that line with the condition  
again:

puts x if 2…5 === x

This is the same as

puts x if 2…(5 === x)

And since the default Object#===, which isn’t overriden by the time we  
reach Integer, returns false, we have:

puts x if 2…false

regardless of x. Now, if 2…false meant a range, like it did other  
times, the Range constructor would raise the expected exception.  
_But_, this syntax appears as the condition of an if statement and the  
special meaning of the … comes into play. Since 2 never “matches” (I  
think it uses the Object#=~ method here?), the switch is never turned  
on.

Whew!

Jacob F.
