# (1..5) === 3 \> true 3 === (1..5) \> false

**URL:** <https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232>\
**Category:** ruby-talk\
**Created:** [15 November 2007 21:25 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232 "2007-11-15T21:25:05Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Chow](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Michael\_Chow](https://rubytalk.org/u/Michael_Chow)\
**Post date:** [15 November 2007 21:25 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/1 "2007-11-15T21:25:05Z")

</div>

(1..5) === 3 \> true  
3 === (1..5) \> false

Is this a bug or expected behavior? From my understanding it shouldn't  
matter on which side of an equal comparison an expression appears.

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

---

<div class="post-metadata">

**Author:** ![Todd\_Benson](https://avatars.discourse-cdn.com/v4/letter/t/34f0e0/32.png) [@Todd\_Benson](https://rubytalk.org/u/Todd_Benson)\
**Post date:** [15 November 2007 21:39 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/2 "2007-11-15T21:39:41Z")

</div>

It's one of those "you have to read the docs" things. The === method  
for Range is left-sided because it's a method. You can redefine it if  
you want.

class Range  
&nbsp;&nbsp;def ===(o)  
&nbsp;&nbsp;&nbsp;puts o  
&nbsp;&nbsp;end  
end

(1..5) === 3  
# 3  
# =\> nil

> **···**
>
> On Nov 15, 2007 3:25 PM, Michael Chow \<nanostuff@magma.ca\> wrote:
> 
> > (1..5) === 3 \> true  
> > 3 === (1..5) \> false
> > 
> > Is this a bug or expected behavior? From my understanding it shouldn't  
> > matter on which side of an equal comparison an expression appears.  
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [15 November 2007 22:11 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/3 "2007-11-15T22:11:10Z")

</div>

Michael Chow wrote:

> (1..5) === 3 \> true  
> 3 === (1..5) \> false
> 
> Is this a bug or expected behavior? From my understanding it shouldn't  
> matter on which side of an equal comparison an expression appears.

It's normal for the #=== operator to be asymmetric, even though it looks symmetric. The LHS is treated as a \_pattern\_ for matching the RHS.

For example:

String === "foo"

uses different criteria than

"foo" === String

and likewise for

/fo/ === "foo"

vs

"foo" === /fo/

Also, note that #=== is used in case statements.

case 3  
when 1..5  
&nbsp;&nbsp;&nbsp;...  
end

works as you expect, because it is equivalent to

if (1..5) === 3  
&nbsp;&nbsp;&nbsp;...  
end

But this wouldn't make sense:

case 1..5  
when 3  
&nbsp;&nbsp;&nbsp;...  
end

so it really needs to be asymmetric.

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Michael\_Chow](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Michael\_Chow](https://rubytalk.org/u/Michael_Chow)\
**Post date:** [15 November 2007 21:56 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/4 "2007-11-15T21:56:14Z")

</div>

I know it's a method, but why doesn't Fixnum's === work properly with  
ranges?

That should be the expected behavior, the expression is just as true one  
way as it is the other.

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

---

<div class="post-metadata">

**Author:** ![Gavin\_Kistner3](https://avatars.discourse-cdn.com/v4/letter/g/dfb087/32.png) [@Gavin\_Kistner3](https://rubytalk.org/u/Gavin_Kistner3)\
**Post date:** [15 November 2007 22:10 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/5 "2007-11-15T22:10:00Z")

</div>

What do you think "===" means? Hint: it's not the same as "==", or  
"\<\<". And it doesn't mean "is equals to". Obviously (1..5) does not  
equal 3.

The #=== method is called in case statements, and it is up to each  
class to define something reasonable.

case 3  
&nbsp;&nbsp;when 1..5  
&nbsp;&nbsp;&nbsp;&nbsp;puts "(1..5) === 3 means 3 is inside the range."  
&nbsp;&nbsp;when Integer  
&nbsp;&nbsp;&nbsp;&nbsp;puts "Integer === 3 means that 3 is a sort of Integer"  
end

> **···**
>
> On Nov 15, 2:56 pm, Michael Chow \<nanost...@magma.ca\> wrote:
> 
> > I know it's a method, but why doesn't Fixnum's === work properly with  
> > ranges?
> > 
> > That should be the expected behavior, the expression is just as true one  
> > way as it is the other.

---

<div class="post-metadata">

**Author:** ![Giles\_Bowkett](https://avatars.discourse-cdn.com/v4/letter/g/96bed5/32.png) [@Giles\_Bowkett](https://rubytalk.org/u/Giles_Bowkett)\
**Post date:** [16 November 2007 05:16 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/6 "2007-11-16T05:16:16Z")

</div>

> I know it's a method, but why doesn't Fixnum's === work properly with  
> ranges?
> 
> That should be the expected behavior, the expression is just as true one  
> way as it is the other.

I'm reading this as incredibly whiny, childish, and obnoxious, but  
that could be totally my own perception.

The whole point of Ruby is that if you don't want things to happen the  
way they happen, you can rewrite large portions of the language -  
including this piece - with very little effort. So not only is it  
pointless to tell people what the language should do, but also, if you  
really want the language to do that, you can \*\*make\*\* it do that with  
hardly any effort at all.

Anyway. The reason threequals doesn't behave the way you expect it to  
is because you don't know what it's for. It's not something you should  
use in day-to-day code. It's not an equality operator. That's why it  
doesn't have the associative property which equality has. Threequals  
is for defining how a class should be evaluated in a case/when  
statement. Unless you're defining how a class should be evaluated in a  
case/when, you shouldn't be using threequals.

So threequals is in fact working properly. You just don't know how to  
use it. The way to use it is to define a new class and then use  
threequals to define how a case/when will evaluate that class. Many,  
many people will never ever need to do this, because it's a relatively  
esoteric use case.

More detail, and less grumpiness:

[http://gilesbowkett.blogspot.com/2007/11/what-is-threequals.html](http://gilesbowkett.blogspot.com/2007/11/what-is-threequals.html)

> **···**
>
> --  
> Giles Bowkett
> 
> Podcast: [http://hollywoodgrit.blogspot.com](http://hollywoodgrit.blogspot.com)  
> Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
> Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
> Tumblelog: [http://giles.tumblr.com](http://giles.tumblr.com)

---

<div class="post-metadata">

**Author:** ![Alex\_Young](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@Alex\_Young](https://rubytalk.org/u/Alex_Young)\
**Post date:** [15 November 2007 22:19 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/7 "2007-11-15T22:19:55Z")

</div>

Phrogz wrote:

> **···**
>
> > On Nov 15, 2:56 pm, Michael Chow \<nanost...@magma.ca\> wrote:
> > 
> > > I know it's a method, but why doesn't Fixnum's === work properly with  
> > > ranges?
> > > 
> > > That should be the expected behavior, the expression is just as true one  
> > > way as it is the other.
> > 
> > What do you think "===" means? Hint: it's not the same as "==", or  
> > "\<\<". And it doesn't mean "is equals to". Obviously (1..5) does not  
> > equal 3.
> > 
> > The #=== method is called in case statements, and it is up to each  
> > class to define something reasonable.
> > 
> > case 3  
> > &nbsp;&nbsp;when 1..5  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts "(1..5) === 3 means 3 is inside the range."  
> > &nbsp;&nbsp;when Integer  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts "Integer === 3 means that 3 is a sort of Integer"  
> > end
> 
> Mentally, I parse "===" as "contains". That requires a little mental judo for RegExps, but that's a good thing 🙂
> 
> --  
> Alex

---

<div class="post-metadata">

**Author:** ![Francis\_Burton](https://avatars.discourse-cdn.com/v4/letter/f/c67d28/32.png) [@Francis\_Burton](https://rubytalk.org/u/Francis_Burton)\
**Post date:** [29 March 2008 19:13 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/8 "2008-03-29T19:13:54Z")

</div>

Giles Bowkett wrote:

> The whole point of Ruby is that if you don't want things to happen the  
> way they happen, you can rewrite large portions of the language -  
> including this piece - with very little effort. So not only is it  
> pointless to tell people what the language should do, but also, if you  
> really want the language to do that, you can \*\*make\*\* it do that with  
> hardly any effort at all.

Is there a construct like this in Ruby?

if x in (1..5)

This seems a lot more intuitive and easier to read than "(1..5) === x",  
so is it possible to modify the language to make it do that?

Francis  
(Ruby nuby)

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

---

<div class="post-metadata">

**Author:** ![Thomas\_Wieczorek](https://avatars.discourse-cdn.com/v4/letter/t/e47c2d/32.png) [@Thomas\_Wieczorek](https://rubytalk.org/u/Thomas_Wieczorek)\
**Post date:** [29 March 2008 19:18 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/9 "2008-03-29T19:18:02Z")

</div>

You can use Enumerable#include?.

if (1..5).include?(x)

> **···**
>
> On Sat, Mar 29, 2008 at 8:13 PM, Francis Burton \<fburton@nyx.net\> wrote:
> 
> > Is there a construct like this in Ruby?
> > 
> > if x in (1..5)

---

<div class="post-metadata">

**Author:** ![Sebastian\_Hungereck1](https://avatars.discourse-cdn.com/v4/letter/s/3ab097/32.png) [@Sebastian\_Hungereck1](https://rubytalk.org/u/Sebastian_Hungereck1)\
**Post date:** [29 March 2008 19:24 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/10 "2008-03-29T19:24:26Z")

</div>

Francis Burton wrote:

> Is there a construct like this in Ruby?
> 
> if x in (1..5)
> 
> This seems a lot more intuitive and easier to read than "(1..5) === x",  
> so is it possible to modify the language to make it do that?

First of all: You usually wouldn't use ===, you'd use (1..5).include? x  
which is more readable in that it tells the reader what it does (=== is  
really only used for things like case and grep - you rarely (if ever) use  
it explicitly).  
To answer your question: Yes, it is:  
class Object  
&nbsp;&nbsp;def in?(collection)  
&nbsp;&nbsp;&nbsp;&nbsp;collection.include? self  
&nbsp;&nbsp;end  
end

if x.in? 1..5  
&nbsp;&nbsp;...  
end

For numbers there's also x.between?(1,5)

HTH,  
Sebastian

> **···**
>
> --  
> NP: Anathema - Harmonium  
> Jabber: sepp2k@jabber.org  
> ICQ: 205544826

---

<div class="post-metadata">

**Author:** ![Marcin\_Miel\_ynski](https://avatars.discourse-cdn.com/v4/letter/m/ba9def/32.png) [@Marcin\_Miel\_ynski](https://rubytalk.org/u/Marcin_Miel_ynski)\
**Post date:** [29 March 2008 19:25 UTC](https://rubytalk.org/t/1-5-3-true-3-1-5-false/42232/11 "2008-03-29T19:25:13Z")

</div>

Francis Burton pisze:

> Giles Bowkett wrote:
> 
> > The whole point of Ruby is that if you don't want things to happen the  
> > way they happen, you can rewrite large portions of the language -  
> > including this piece - with very little effort. So not only is it  
> > pointless to tell people what the language should do, but also, if you  
> > really want the language to do that, you can \*\*make\*\* it do that with  
> > hardly any effort at all.
> 
> Is there a construct like this in Ruby?
> 
> if x in (1..5)
> 
> This seems a lot more intuitive and easier to read than "(1..5) === x",  
> so is it possible to modify the language to make it do that?
> 
> Francis  
> (Ruby nuby)

Use (1..5).include? x. Ruby tends to use methods instead of abusing keywords.

lopex
