From: Rick DeNatale Date: 2010-05-17T22:12:26+09:00 Subject: Re: Range on strings. On Mon, May 17, 2010 at 8:29 AM, David A. Black 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