APIdock / Ruby
/
method

step

ruby latest stable - Class: Range
step(p1 = v1)
public

Iterates over the range, passing each nth element to the block. If begin and end are numeric, n is added for each iteration. Otherwise step invokes succ to iterate through range elements.

If no block is given, an enumerator is returned instead.

range = Xs.new (1)..Xs.new (10)
range.step (2) {|x| puts x}
puts
range.step (3) {|x| puts x}

produces:

 1 x
 3 xxx
 5 xxxxx
 7 xxxxxxx
 9 xxxxxxxxx
 1 x
 4 xxxx
 7 xxxxxxx
10 xxxxxxxxxx

See Range for the definition of class Xs.

static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
 VALUE b, e, step, tmp;
 RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);
 b = RANGE_BEG(range);
 e = RANGE_END(range);
 if (argc == 0) {
 step = INT2FIX(1);
 }
 else {
 rb_scan_args(argc, argv, "01", &step);
 step = check_step_domain(step);
 }
 if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
 long end = FIX2LONG(e);
 long i, unit = FIX2LONG(step);
 if (!EXCL(range))
 end += 1;
 i = FIX2LONG(b);
 while (i < end) {
 rb_yield(LONG2NUM(i));
 if (i + unit < i) break;
 i += unit;
 }
 }
 else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
 VALUE args[2], iter[2];
 args[0] = rb_sym2str(e);
 args[1] = EXCL(range) ? Qtrue : Qfalse;
 iter[0] = INT2FIX(1);
 iter[1] = step;
 rb_block_call(rb_sym2str(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
 }
 else if (ruby_float_step(b, e, step, EXCL(range))) {
 /* done */
 }
 else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
 !NIL_P(rb_check_to_integer(b, "to_int")) ||
 !NIL_P(rb_check_to_integer(e, "to_int"))) {
 ID op = EXCL(range) ? '<' : idLE;
 VALUE v = b;
 int i = 0;
 while (RTEST(rb_funcall(v, op, 1, e))) {
 rb_yield(v);
 i++;
 v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
 }
 }
 else {
 tmp = rb_check_string_type(b);
 if (!NIL_P(tmp)) {
 VALUE args[2], iter[2];
 b = tmp;
 args[0] = e;
 args[1] = EXCL(range) ? Qtrue : Qfalse;
 iter[0] = INT2FIX(1);
 iter[1] = step;
 rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
 }
 else {
 VALUE args[2];
 if (!discrete_object_p(b)) {
 rb_raise(rb_eTypeError, "can't iterate from %s",
 rb_obj_classname(b));
 }
 args[0] = INT2FIX(1);
 args[1] = step;
 range_each_func(range, step_i, (VALUE)args);
 }
 }
 return range;
}

AltStyle によって変換されたページ (->オリジナル) /