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.

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,
    then
        a. if the value is nil, or an empty string, or a string with
length > 1 return false
        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

     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.

-- 
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale