summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--range.c7
-rw-r--r--test/ruby/test_range.rb9
3 files changed, 20 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index b5fc76c7d7..7824dfc5d7 100644
--- a/NEWS
+++ b/NEWS
@@ -217,6 +217,10 @@ sufficient information, see the ChangeLog file or Redmine
* `Range`
+ * New methods:
+
+ * Added `Range#%` instance method. [Feature #14697]
+
* Incompatible changes:
* `Range#===` now uses `#cover?` instead of `#include?` method.
diff --git a/range.c b/range.c
index d781af3f2e..297303ba9a 100644
--- a/range.c
+++ b/range.c
@@ -497,6 +497,12 @@ range_step(int argc, VALUE *argv, VALUE range)
return range;
}
+static VALUE
+range_percent_step(VALUE range, VALUE step)
+{
+ return range_step(1, &step, range);
+}
+
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
union int64_double {
int64_t i;
@@ -1549,6 +1555,7 @@ Init_Range(void)
rb_define_method(rb_cRange, "hash", range_hash, 0);
rb_define_method(rb_cRange, "each", range_each, 0);
rb_define_method(rb_cRange, "step", range_step, -1);
+ rb_define_method(rb_cRange, "%", range_percent_step, 1);
rb_define_method(rb_cRange, "bsearch", range_bsearch, 0);
rb_define_method(rb_cRange, "begin", range_begin, 0);
rb_define_method(rb_cRange, "end", range_end, 0);
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index c1d9dc1848..f58d1f817c 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -322,6 +322,15 @@ class TestRange < Test::Unit::TestCase
assert_equal(["a", "b", "c"], a)
end
+ def test_percent_step
+ aseq = (1..10) % 2
+ assert_equal(Enumerator::ArithmeticSequence, aseq.class)
+ assert_equal(1, aseq.begin)
+ assert_equal(10, aseq.end)
+ assert_equal(2, aseq.step)
+ assert_equal([1, 3, 5, 7, 9], aseq.to_a)
+ end
+
def test_step_ruby_core_35753
assert_equal(6, (1...6.3).step.to_a.size)
assert_equal(5, (1.1...6).step.to_a.size)