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
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
On Fri, May 14, 2010 at 11:40 AM, Vikrant C. [email protected]
wrote:
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 4:40 AM, Vikrant C. [email protected]
wrote:
I’m using ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux] on
Ubuntu 10.04 x64
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)
/*
rng === obj => true or false
rng.member?(val) => true or false
rng.include?(val) => true or false
true
if obj is an element offalse
otherwise. Conveniently,===
is the comparison operator used bycase
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
high
*/
static VALUE
range_include(range, val)
VALUE range, val;
{
VALUE beg, end;
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
if (r_le(beg, val)) {
if (EXCL(range)) {
if (r_lt(val, end)) return Qtrue;
}
else {
if (r_le(val, end)) return Qtrue;
}
}
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, 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)
/*
enum.to_a => array
enum.entries => array
(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)
int argc;
VALUE *argv;
VALUE obj;
{
VALUE ary = rb_ary_new();
rb_block_call(obj, id_each, argc, argv, collect_all, ary);
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)
/*
array.include?(obj) -> true or false
true
if the given object is present in==
false
otherwise.a = [ "a", "b", "c" ]
a.include?("b") #=> true
a.include?("z") #=> false
*/
VALUE
rb_ary_includes(ary, item)
VALUE ary;
VALUE item;
{
long i;
for (i=0; i<RARRAY(ary)->len; i++) {
if (rb_equal(RARRAY(ary)->ptr[i], item)) {
return Qtrue;
}
}
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)
On Sat, May 15, 2010 at 8:25 AM, MrZombie [email protected]
wrote:
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.
-MrZombieI am not able to replicate that behaviour.
$ 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 2010-05-14 05:37:37 -0400, Vikrant C. 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.
Hi –
On Fri, 14 May 2010, Vikrant C. wrote:
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
–
David A. Black, Senior Developer, Cyrus Innovation Inc.
THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com
On Mon, May 17, 2010 at 8:29 AM, David A. Black [email protected]
wrote:
(‘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 x64As 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.
Right comparisons here means that the value is >= the beginning and
either < or <= the end depending on whether the range excludes 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”))’
trueinclude? 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: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
On May 14, 2:37 pm, Vikrant C. [email protected] wrote:
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
On 2010-05-17 07:53:34 -0400, Vikrant C. said:
(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 x64Probably because the way Strings are compared, “AA” < “Z” #=> true
Just for the kicks, I tried with (‘a’…‘z’).include? ‘aa’
Guess what? False.
2010/5/17 David A. Black [email protected]:
the old include? is found in Range#cover?
$ ruby191 -e ‘p((“A”…“Z”).include?(“AA”))’
false
$ ruby191 -e ‘p((“A”…“Z”).cover?(“AA”))’
trueinclude? 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.
Kind regards
robert
On Mon, 17 May 2010, Rick DeNatale wrote:
It returns “true”, while
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.
[snip]
Thanks. I was being lazy, so I’m glad for the further info
David
–
David A. Black, Senior Developer, Cyrus Innovation Inc.
THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com
Vikrant C. wrote:
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.
Hi –
On Mon, 17 May 2010, Robert K. wrote:
It returns “true”, while
on a range is, I think, the same as .to_a.include? and the behavior of
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:
$ ruby191 -e “p((1…10).include?(3.4))”
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
–
David A. Black, Senior Developer, Cyrus Innovation Inc.
THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs