# Range on strings

**URL:** <https://rubytalk.org/t/range-on-strings/58521>\
**Category:** ruby-talk\
**Created:** [14 May 2010 09:40 UTC](https://rubytalk.org/t/range-on-strings/58521 "2010-05-14T09:40:20Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vikrant\_Chaudhary](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@Vikrant\_Chaudhary](https://rubytalk.org/u/Vikrant_Chaudhary)\
**Post date:** [14 May 2010 09:40 UTC](https://rubytalk.org/t/range-on-strings/58521/1 "2010-05-14T09:40:20Z")

</div>

Hi,  
If I do -

('A'..'Z').include?('AA')

It returns "true", while

('A'..'Z').to\_a.include?('AA')

(of course) returns "false". Is it intentional or possibly a bug?  
I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
Ubuntu 10.04 x64

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [14 May 2010 10:09 UTC](https://rubytalk.org/t/range-on-strings/58521/2 "2010-05-14T10:09:33Z")

</div>

I do not know if it is a bug, but the behavior has changed in Ruby1.9,  
thus I guess it was at least considered, "surprising" in 1.8.  
Cheers  
R.

> **···**
>
> On Fri, May 14, 2010 at 11:40 AM, Vikrant Chaudhary \<[nasa42@gmail.com](mailto:nasa42@gmail.com)\> wrote:
> 
> --  
> The best way to predict the future is to invent it.  
> -- Alan Kay

---

<div class="post-metadata">

**Author:** ![Josh\_Cheek](https://avatars.discourse-cdn.com/v4/letter/j/e79b87/32.png) [@Josh\_Cheek](https://rubytalk.org/u/Josh_Cheek)\
**Post date:** [15 May 2010 02:01 UTC](https://rubytalk.org/t/range-on-strings/58521/3 "2010-05-15T02:01:16Z")

</div>

I think the problem is that on 1.8 it checks include by seeing if the value  
is greater than or equal to the beginning value, and less then or equal to  
the end value, since string comparison would have "A" \< "AA" \< "Z", it  
returns true.

([http://svn.ruby-lang.org/repos/ruby/branches/ruby\_1\_8/range.c\](http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/range.c%5C))

/\*  
\* call-seq:  
\* rng === obj =\> true or false  
\* rng.member?(val) =\> true or false  
\* rng.include?(val) =\> true or false

> **···**
>
> On Fri, May 14, 2010 at 4:40 AM, Vikrant Chaudhary \<nasa42@gmail.com\> wrote:
> 
> > Hi,  
> > If I do -
> > 
> > ('A'..'Z').include?('AA')
> > 
> > It returns "true", while
> > 
> > ('A'..'Z').to\_a.include?('AA')
> > 
> > (of course) returns "false". Is it intentional or possibly a bug?  
> > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > Ubuntu 10.04 x64
> 
> \*  
> \* Returns \<code\>true\</code\> if \<i\>obj\</i\> is an element of  
> \* \<i\>rng\</i\>, \<code\>false\</code\> otherwise. Conveniently,  
> \* \<code\>===\</code\> is the comparison operator used by  
> \* \<code\>case\</code\> statements.  
> \*  
> \* case 79  
> \* when 1..50 then print "low\n"  
> \* when 51..75 then print "medium\n"  
> \* when 76..100 then print "high\n"  
> \* end  
> \*  
> \* \<em\>produces:\</em\>  
> \*  
> \* high  
> \*/
> 
> static VALUE  
> range\_include(range, val)  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE range, val;  
> {  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE beg, end;
> 
> &nbsp;&nbsp;&nbsp;&nbsp;beg = rb\_ivar\_get(range, id\_beg);  
> &nbsp;&nbsp;&nbsp;&nbsp;end = rb\_ivar\_get(range, id\_end);  
> &nbsp;&nbsp;&nbsp;&nbsp;if (r\_le(beg, val)) {  
> &nbsp;&nbsp;if (EXCL(range)) {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (r\_lt(val, end)) return Qtrue;  
> &nbsp;&nbsp;}  
> &nbsp;&nbsp;else {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (r\_le(val, end)) return Qtrue;  
> &nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;return Qfalse;  
> }
> 
> However, when it converts to an array, that is a method from Enumerable. I'm  
> not initiated enough to figure out how it's C code works, but my  
> understanding is that it uses #succ (I got that from this thread  
> [Bizarre Range behavior - Ruby - Ruby-Forum](http://www.ruby-forum.com/topic/192758#new), but please correct me if I  
> misunderstood) to iterate from the beginning element to the end element, to  
> create the array. Here is it's code, if you understand it, feel free to  
> explain.  
> ([http://svn.ruby-lang.org/repos/ruby/branches/ruby\_1\_8/enum.c\](http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/enum.c%5C))
> 
> /\*  
> \* call-seq:  
> \* enum.to\_a =\> array  
> \* enum.entries =\> array  
> \*  
> \* Returns an array containing the items in \<i\>enum\</i\>.  
> \*  
> \* (1..7).to\_a #=\> [1, 2, 3, 4, 5, 6, 7]  
> \* { 'a'=\>1, 'b'=\>2, 'c'=\>3 }.to\_a #=\> [["a", 1], ["b", 2], ["c", 3]]  
> \*/  
> static VALUE  
> enum\_to\_a(argc, argv, obj)  
> &nbsp;&nbsp;&nbsp;&nbsp;int argc;  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE \*argv;  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE obj;  
> {  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE ary = rb\_ary\_new();
> 
> &nbsp;&nbsp;&nbsp;&nbsp;rb\_block\_call(obj, id\_each, argc, argv, collect\_all, ary);
> 
> &nbsp;&nbsp;&nbsp;&nbsp;return ary;  
> }
> 
> Then Array#include iterates through each of it's elements to check if it  
> contains the desired element  
> ([http://svn.ruby-lang.org/repos/ruby/branches/ruby\_1\_8/array.c\](http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/array.c%5C))
> 
> /\*  
> \* call-seq:  
> \* array.include?(obj) -\> true or false  
> \*  
> \* Returns \<code\>true\</code\> if the given object is present in  
> \* \<i\>self\</i\> (that is, if any object \<code\>==\</code\> \<i\>anObject\</i\>),  
> \* \<code\>false\</code\> otherwise.  
> \*  
> \* a = ["a", "b", "c"]  
> \* a.include?("b") #=\> true  
> \* a.include?("z") #=\> false  
> \*/
> 
> VALUE  
> rb\_ary\_includes(ary, item)  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE ary;  
> &nbsp;&nbsp;&nbsp;&nbsp;VALUE item;  
> {  
> &nbsp;&nbsp;&nbsp;&nbsp;long i;
> 
> &nbsp;&nbsp;&nbsp;&nbsp;for (i=0; i\<RARRAY(ary)-\>len; i++) {  
> &nbsp;&nbsp;if (rb\_equal(RARRAY(ary)-\>ptr[i], item)) {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Qtrue;  
> &nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;return Qfalse;  
> }
> 
> The elements the array contains are  
> $ ruby -e "p ('A'..'Z').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"]  
> So "AA" is not found, and thus it returns false.
> 
> I honestly don't know about 1.9, I tried looking at it's code, but I don't  
> understand it.  
> ([http://svn.ruby-lang.org/repos/ruby/branches/ruby\_1\_9\_1/range.c\](http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_9_1/range.c%5C))

---

<div class="post-metadata">

**Author:** ![MrZombie](https://avatars.discourse-cdn.com/v4/letter/m/258eb7/32.png) [@MrZombie](https://rubytalk.org/u/MrZombie)\
**Post date:** [15 May 2010 13:25 UTC](https://rubytalk.org/t/range-on-strings/58521/4 "2010-05-15T13:25:11Z")

</div>

Mac OS X Snow Leopard running Ruby 1.9.1, same behavior.

I notice that it returns false if no element of the string is included in the range.

For example, given r = ('A'..'Z'): r.include?('RUBY') # returns true  
and: r.include?('Ruby') # also true  
but: r.include?('ruby') # is false.

> **···**
>
> On 2010-05-14 05:37:37 -0400, Vikrant Chaudhary said:
> 
> > Is it intentional or possibly a bug?  
> > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > Ubuntu 10.04 x64
> 
> --  
> Thank you for your brain.  
> -MrZombie

---

<div class="post-metadata">

**Author:** ![Vikrant\_Chaudhary](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@Vikrant\_Chaudhary](https://rubytalk.org/u/Vikrant_Chaudhary)\
**Post date:** [17 May 2010 11:55 UTC](https://rubytalk.org/t/range-on-strings/58521/5 "2010-05-17T11:55:07Z")

</div>

Probably because the way Strings are compared, "AA" \< "Z" #=\> true

> **···**
>
> On May 14, 2:37 pm, Vikrant Chaudhary \<nas...@gmail.com\> wrote:
> 
> > Hi,  
> > If I do -
> > 
> > ('A'..'Z').include?('AA')
> > 
> > It returns "true", while
> > 
> > ('A'..'Z').to\_a.include?('AA')
> > 
> > (of course) returns "false". Is it intentional or possibly a bug?  
> > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > Ubuntu 10.04 x64

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [17 May 2010 12:29 UTC](https://rubytalk.org/t/range-on-strings/58521/6 "2010-05-17T12:29:46Z")

</div>

Hi --

> Hi,  
> If I do -
> 
> ('A'..'Z').include?('AA')
> 
> It returns "true", while
> 
> ('A'..'Z').to\_a.include?('AA')
> 
> (of course) returns "false". Is it intentional or possibly a bug?  
> I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> Ubuntu 10.04 x64

As per the other answers, it's because ('A'..'Z').to\_a is an array of  
discrete values, whereas ('A'..'Z') is a range with a start and end.  
I'll just add that in Ruby 1.9, things have changed so that include?  
on a range is, I think, the same as .to\_a.include? and the behavior of  
the old include? is found in Range#cover?

$ ruby191 -e 'p(("A".."Z").include?("AA"))'  
false  
$ ruby191 -e 'p(("A".."Z").cover?("AA"))'  
true

include? is also available under the name member?, which I think is a  
little clearer (both because include? used to mean something else, and  
because being a "member" of a range doesn't really make sense so it  
almost has to mean something other than just being within the range).

David

> **···**
>
> On Fri, 14 May 2010, Vikrant Chaudhary wrote:
> 
> --  
> David A. Black, Senior Developer, Cyrus Innovation Inc.
> 
> THE Ruby training with Black/Brown/McAnally  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMPLEAT Coming to Chicago area, June 18-19, 2010!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RUBYIST [http://www.compleatrubyist.com](http://www.compleatrubyist.com)

---

<div class="post-metadata">

**Author:** ![Michael\_W\_Ryder2](https://avatars.discourse-cdn.com/v4/letter/m/e99b99/32.png) [@Michael\_W\_Ryder2](https://rubytalk.org/u/Michael_W_Ryder2)\
**Post date:** [17 May 2010 18:55 UTC](https://rubytalk.org/t/range-on-strings/58521/7 "2010-05-17T18:55:13Z")

</div>

Vikrant Chaudhary wrote:

> Hi,  
> If I do -
> 
> ('A'..'Z').include?('AA')
> 
> It returns "true", while
> 
> ('A'..'Z').to\_a.include?('AA')
> 
> (of course) returns "false". Is it intentional or possibly a bug?  
> I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> Ubuntu 10.04 x64

Using ruby 1.9.1 and Windows Vista both examples return false.

---

<div class="post-metadata">

**Author:** ![Josh\_Cheek](https://avatars.discourse-cdn.com/v4/letter/j/e79b87/32.png) [@Josh\_Cheek](https://rubytalk.org/u/Josh_Cheek)\
**Post date:** [15 May 2010 18:08 UTC](https://rubytalk.org/t/range-on-strings/58521/8 "2010-05-15T18:08:48Z")

</div>

$ rvm use 1.9.1  
Using ruby 1.9.1 p378

$ irb  
ruby-1.9.1-p378 \> r = 'A'..'Z'  
=\> "A".."Z"  
ruby-1.9.1-p378 \> r.include? 'Ruby'  
=\> false  
ruby-1.9.1-p378 \> r.include? 'RUBY'  
=\> false  
ruby-1.9.1-p378 \> r.include? 'ruby'  
=\> false  
ruby-1.9.1-p378 \> exit

$ ruby -v  
ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-darwin10.3.0]

> **···**
>
> On Sat, May 15, 2010 at 8:25 AM, MrZombie \<mrzombie@thezombie.net\> wrote:
> 
> > On 2010-05-14 05:37:37 -0400, Vikrant Chaudhary said:
> > 
> > Is it intentional or possibly a bug?
> > 
> > > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > > Ubuntu 10.04 x64
> > 
> > Mac OS X Snow Leopard running Ruby 1.9.1, same behavior.
> > 
> > I notice that it returns false if no element of the string is included in  
> > the range.
> > 
> > For example, given r = ('A'..'Z'): r.include?('RUBY') # returns true  
> > and: r.include?('Ruby') # also true  
> > but: r.include?('ruby') # is false.  
> > --  
> > Thank you for your brain.  
> > -MrZombie
> > 
> > I am not able to replicate that behaviour.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [17 May 2010 13:12 UTC](https://rubytalk.org/t/range-on-strings/58521/9 "2010-05-17T13:12:26Z")

</div>

> Hi --
> 
> > Hi,  
> > If I do -
> > 
> > ('A'..'Z').include?('AA')
> > 
> > It returns "true", while
> > 
> > ('A'..'Z').to\_a.include?('AA')
> > 
> > (of course) returns "false". Is it intentional or possibly a bug?  
> > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > Ubuntu 10.04 x64
> 
> As per the other answers, it's because ('A'..'Z').to\_a is an array of  
> discrete values, whereas ('A'..'Z') is a range with a start and end.  
> I'll just add that in Ruby 1.9, things have changed so that include?  
> on a range is, I think, the same as .to\_a.include?

Not exactly. Range#include? for Ruby 1.9 has a few special cases.

1. If the beginning or end of the range is numeric, it just uses the  
right comparisons between the value being tested and the beginning and  
end.

Right comparisons here means that the value is \>= the beginning and  
either \< or \<= the end depending on whether the range excludes the  
end.

2. If the beginning and end of the range are both strings of length 1,  
&nbsp;&nbsp;&nbsp;&nbsp;then  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a. if the value is nil, or an empty string, or a string with  
length \> 1 return false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b. if the beginning, end and value are all ASCII characters  
then return the result of the right comparisons between the value, the  
beginning and the end.

At the end if it hasn't short circuited it invokes super which uses  
Enumeration#include? (which is an alias for member?) which does the  
equivalent of

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self detect (|element| element == value}

Which is like to\_a.include?(value) but short circuits the enumeration  
when it finds a hit.

> and the behavior of  
> the old include? is found in Range#cover?

> $ ruby191 -e 'p(("A".."Z").include?("AA"))'  
> false  
> $ ruby191 -e 'p(("A".."Z").cover?("AA"))'  
> true
> 
> include? is also available under the name member?, which I think is a  
> little clearer (both because include? used to mean something else, and  
> because being a "member" of a range doesn't really make sense so it  
> almost has to mean something other than just being within the range).

That's a bit subjective I think, it depends on whether or not you  
think of a Range as a collection or not. Personally I can think of it  
either way depending on the situation.

> **···**
>
> On Mon, May 17, 2010 at 8:29 AM, David A. Black \<dblack@rubypal.com\> wrote:
> 
> > On Fri, 14 May 2010, Vikrant Chaudhary wrote:
> 
> --  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
> Twitter: @RickDeNatale  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![MrZombie](https://avatars.discourse-cdn.com/v4/letter/m/258eb7/32.png) [@MrZombie](https://rubytalk.org/u/MrZombie)\
**Post date:** [17 May 2010 14:40 UTC](https://rubytalk.org/t/range-on-strings/58521/10 "2010-05-17T14:40:10Z")

</div>

Just for the kicks, I tried with ('a'..'z').include? 'aa'

Guess what? False.

> **···**
>
> On 2010-05-17 07:53:34 -0400, Vikrant Chaudhary said:
> 
> > On May 14, 2:37 pm, Vikrant Chaudhary \<nas...@gmail.com\> wrote:
> > 
> > > Hi,  
> > > If I do -
> > > 
> > > ('A'..'Z').include?('AA')
> > > 
> > > It returns "true", while
> > > 
> > > ('A'..'Z').to\_a.include?('AA')
> > > 
> > > (of course) returns "false". Is it intentional or possibly a bug?  
> > > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > > Ubuntu 10.04 x64
> > 
> > Probably because the way Strings are compared, "AA" \< "Z" #=\> true
> 
> --  
> Thank you for your brain.  
> -MrZombie

---

<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:** [17 May 2010 14:48 UTC](https://rubytalk.org/t/range-on-strings/58521/11 "2010-05-17T14:48:26Z")

</div>

Throwing just my cent in here: I believe the solution in 1.9.\* is  
better because here behavior of #include? is consistent with other  
collection types: e.include?(x) == true \<=\> e.any? {|y| x == y} in  
other words, #include? is true only if the element is also seen during  
iteration.

Kind regards

robert

> **···**
>
> 2010/5/17 David A. Black \<dblack@rubypal.com\>:
> 
> > Hi --
> > 
> > On Fri, 14 May 2010, Vikrant Chaudhary wrote:
> > 
> > > Hi,  
> > > If I do -
> > > 
> > > ('A'..'Z').include?('AA')
> > > 
> > > It returns "true", while
> > > 
> > > ('A'..'Z').to\_a.include?('AA')
> > > 
> > > (of course) returns "false". Is it intentional or possibly a bug?  
> > > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > > Ubuntu 10.04 x64
> > 
> > As per the other answers, it's because ('A'..'Z').to\_a is an array of  
> > discrete values, whereas ('A'..'Z') is a range with a start and end.  
> > I'll just add that in Ruby 1.9, things have changed so that include?  
> > on a range is, I think, the same as .to\_a.include? and the behavior of  
> > the old include? is found in Range#cover?
> > 
> > $ ruby191 -e 'p(("A".."Z").include?("AA"))'  
> > false  
> > $ ruby191 -e 'p(("A".."Z").cover?("AA"))'  
> > true
> > 
> > include? is also available under the name member?, which I think is a  
> > little clearer (both because include? used to mean something else, and  
> > because being a "member" of a range doesn't really make sense so it  
> > almost has to mean something other than just being within the range).
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [17 May 2010 14:53 UTC](https://rubytalk.org/t/range-on-strings/58521/12 "2010-05-17T14:53:50Z")

</div>

[snip]

Thanks. I was being lazy, so I'm glad for the further info 🙂

David

> **···**
>
> On Mon, 17 May 2010, Rick DeNatale wrote:
> 
> > On Mon, May 17, 2010 at 8:29 AM, David A. Black \<dblack@rubypal.com\> wrote:
> > 
> > > Hi --
> > > 
> > > On Fri, 14 May 2010, Vikrant Chaudhary wrote:
> > > 
> > > > Hi,  
> > > > If I do -
> > > > 
> > > > ('A'..'Z').include?('AA')
> > > > 
> > > > It returns "true", while
> > > > 
> > > > ('A'..'Z').to\_a.include?('AA')
> > > > 
> > > > (of course) returns "false". Is it intentional or possibly a bug?  
> > > > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > > > Ubuntu 10.04 x64
> > > 
> > > As per the other answers, it's because ('A'..'Z').to\_a is an array of  
> > > discrete values, whereas ('A'..'Z') is a range with a start and end.  
> > > I'll just add that in Ruby 1.9, things have changed so that include?  
> > > on a range is, I think, the same as .to\_a.include?
> > 
> > Not exactly. Range#include? for Ruby 1.9 has a few special cases.
> 
> --  
> David A. Black, Senior Developer, Cyrus Innovation Inc.
> 
> THE Ruby training with Black/Brown/McAnally  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMPLEAT Coming to Chicago area, June 18-19, 2010!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RUBYIST [http://www.compleatrubyist.com](http://www.compleatrubyist.com)

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [17 May 2010 15:01 UTC](https://rubytalk.org/t/range-on-strings/58521/13 "2010-05-17T15:01:12Z")

</div>

Hi --

> > Hi --
> > 
> > > Hi,  
> > > If I do -
> > > 
> > > ('A'..'Z').include?('AA')
> > > 
> > > It returns "true", while
> > > 
> > > ('A'..'Z').to\_a.include?('AA')
> > > 
> > > (of course) returns "false". Is it intentional or possibly a bug?  
> > > I'm using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86\_64-linux] on  
> > > Ubuntu 10.04 x64
> > 
> > As per the other answers, it's because ('A'..'Z').to\_a is an array of  
> > discrete values, whereas ('A'..'Z') is a range with a start and end.  
> > I'll just add that in Ruby 1.9, things have changed so that include?  
> > on a range is, I think, the same as .to\_a.include? and the behavior of  
> > the old include? is found in Range#cover?
> > 
> > $ ruby191 -e 'p(("A".."Z").include?("AA"))'  
> > false  
> > $ ruby191 -e 'p(("A".."Z").cover?("AA"))'  
> > true
> > 
> > include? is also available under the name member?, which I think is a  
> > little clearer (both because include? used to mean something else, and  
> > because being a "member" of a range doesn't really make sense so it  
> > almost has to mean something other than just being within the range).
> 
> Throwing just my cent in here: I believe the solution in 1.9.\* is  
> better because here behavior of #include? is consistent with other  
> collection types: e.include?(x) == true \<=\> e.any? {|y| x == y} in  
> other words, #include? is true only if the element is also seen during  
> iteration.

Although as Rick points out:

&nbsp;&nbsp;&nbsp;$ ruby191 -e "p((1..10).include?(3.4))"  
&nbsp;&nbsp;&nbsp;true

which I hadn't taken into account in my too-simple summary of 1.9's  
Range#include?. I'm not sure what the underlying principle is that  
causes that last case to be true while the "A".."Z" including "AA" is  
false, though.

David

> **···**
>
> On Mon, 17 May 2010, Robert Klemme wrote:
> 
> > 2010/5/17 David A. Black \<dblack@rubypal.com\>:
> > 
> > > On Fri, 14 May 2010, Vikrant Chaudhary wrote:
> 
> --  
> David A. Black, Senior Developer, Cyrus Innovation Inc.
> 
> THE Ruby training with Black/Brown/McAnally  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMPLEAT Coming to Chicago area, June 18-19, 2010!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RUBYIST [http://www.compleatrubyist.com](http://www.compleatrubyist.com)
