1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* range.c: Support for range.step.size

[Feature #6636]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37517 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
marcandre 2012-11-06 17:15:00 +00:00
parent 28d8bf902d
commit faed90d814
2 changed files with 30 additions and 1 deletions

25
range.c
View file

@ -315,6 +315,29 @@ discrete_object_p(VALUE obj)
return rb_respond_to(obj, id_succ);
}
static VALUE
range_step_size(VALUE range, VALUE args)
{
VALUE b = RANGE_BEG(range), e = RANGE_END(range);
VALUE step = INT2FIX(1);
if (args) {
step = RARRAY_PTR(args)[0];
if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
step = rb_to_int(step);
}
}
if (rb_funcall(step, '<', 1, INT2FIX(0))) {
rb_raise(rb_eArgError, "step can't be negative");
}
else if (!rb_funcall(step, '>', 1, INT2FIX(0))) {
rb_raise(rb_eArgError, "step can't be 0");
}
if (rb_obj_is_kind_of(b, rb_cNumeric) && rb_obj_is_kind_of(e, rb_cNumeric)) {
return num_interval_step_size(b, e, step, EXCL(range));
}
return Qnil;
}
/*
* call-seq:
@ -355,7 +378,7 @@ range_step(int argc, VALUE *argv, VALUE range)
{
VALUE b, e, step, tmp;
RETURN_ENUMERATOR(range, argc, argv);
RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
b = RANGE_BEG(range);
e = RANGE_END(range);

View file

@ -536,6 +536,12 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal 1, 42.step(Float::INFINITY, Float::INFINITY).size
assert_equal 14, 0.1.step(4.2, 0.3).size
assert_equal Float::INFINITY, 42.step(Float::INFINITY, 2).size
assert_equal 10, (1..10).step.size
assert_equal 4, (1..10).step(3).size
assert_equal 3, (1...10).step(3).size
assert_equal Float::INFINITY, (42..Float::INFINITY).step(2).size
assert_raise(ArgumentError){ (1..10).step(-2).size }
end
end