summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--range.c17
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb17
-rw-r--r--test/ruby/test_range.rb10
4 files changed, 41 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 0b8caca210..85ccdac4e5 100644
--- a/NEWS
+++ b/NEWS
@@ -116,6 +116,10 @@ with all sufficient information, see the ChangeLog file or Redmine
* added Random.bytes. [Feature #4938]
+* Range
+
+ * Range#=== now uses #cover? instead of #include? method. [Feature #14575]
+
* String
* String#split yields each substring to the block if given. [Feature #4780]
diff --git a/range.c b/range.c
index 917d24bd83..dcae2b2397 100644
--- a/range.c
+++ b/range.c
@@ -1212,6 +1212,8 @@ range_inspect(VALUE range)
return rb_exec_recursive(inspect_range, range, 0);
}
+static VALUE range_include_internal(VALUE range, VALUE val);
+
/*
* call-seq:
* rng === obj -> true or false
@@ -1234,7 +1236,9 @@ range_inspect(VALUE range)
static VALUE
range_eqq(VALUE range, VALUE val)
{
- return rb_funcall(range, rb_intern("include?"), 1, val);
+ VALUE ret = range_include_internal(range, val);
+ if (ret != Qundef) return ret;
+ return r_cover_p(range, RANGE_BEG(range), RANGE_END(range), val);
}
@@ -1255,6 +1259,14 @@ range_eqq(VALUE range, VALUE val)
static VALUE
range_include(VALUE range, VALUE val)
{
+ VALUE ret = range_include_internal(range, val);
+ if (ret != Qundef) return ret;
+ return rb_call_super(1, &val);
+}
+
+static VALUE
+range_include_internal(VALUE range, VALUE val)
+{
VALUE beg = RANGE_BEG(range);
VALUE end = RANGE_END(range);
int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
@@ -1277,8 +1289,7 @@ range_include(VALUE range, VALUE val)
return Qfalse;
}
}
- /* TODO: ruby_frame->this_func = rb_intern("include?"); */
- return rb_call_super(1, &val);
+ return Qundef;
}
diff --git a/spec/ruby/core/range/case_compare_spec.rb b/spec/ruby/core/range/case_compare_spec.rb
index e0da683649..9a33c5b73b 100644
--- a/spec/ruby/core/range/case_compare_spec.rb
+++ b/spec/ruby/core/range/case_compare_spec.rb
@@ -3,9 +3,18 @@ require_relative 'shared/cover_and_include'
require_relative 'shared/cover'
describe "Range#===" do
- it "returns the result of calling #include? on self" do
- range = 0...10
- range.should_receive(:include?).with(2).and_return(:true)
- (range === 2).should == :true
+ ruby_version_is ""..."2.6" do
+ it "returns the result of calling #include? on self" do
+ range = 0...10
+ range.should_receive(:include?).with(2).and_return(:true)
+ (range === 2).should == :true
+ end
+ end
+
+ ruby_version_is "2.6" do
+ it "returns the result of calling #cover? on self" do
+ range = RangeSpecs::Custom.new(0)..RangeSpecs::Custom.new(10)
+ (range === RangeSpecs::Custom.new(2)).should == true
+ end
end
end
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index 5f2e970324..c98b130456 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -473,6 +473,16 @@ class TestRange < Test::Unit::TestCase
assert_operator(c.new(0)..c.new(10), :===, c.new(5), bug12003)
end
+ def test_eqq_non_iteratable
+ k = Class.new do
+ include Comparable
+ attr_reader :i
+ def initialize(i) @i = i; end
+ def <=>(o); i <=> o.i; end
+ end
+ assert_operator(k.new(0)..k.new(2), :===, k.new(1))
+ end
+
def test_include
assert_include("a".."z", "c")
assert_not_include("a".."z", "5")