naruse e$B$G$9!#e(B
Yukihiro M. wrote:
|> rb_iterate()e$B$K$J$s$i$+$NLdBj$,$"$C$F!"e(Bbl_proce$B$KEO$7$?4X?t$Ge(B
e$B$j$^$;$s!#$N$G!“JQ$J@)8B$G$J$$$N$+$I$&$+$NH=CG$b$G$-$^$;$s!#e(B
rb_iterate()e$BA4HL$,F0$+$J$$$H$$$&$o$1$G$O$J$$$h$&$G$9$,!”$?$He(B
e$B$($Pe(Beach_with_indexe$B$,F0$$$Fe(Bstepe$B$,F0$+$J$$M}M3$C$F$N$O$9$0$Ke(B
e$B%T%s$H$OMh$^$;$s$M!#e(B
range_stepe$B$N>l9ge(B str_step -> step_i -> block
e$B$G$J$1$l$P$$$1$J$$$N$K!"e(B
str_step -> block e$B$H$J$C$F$7$^$C$F$$$k$H$$$&$3$H$G$9$+$M!&!&!&!)e(B
e$BDI$C$F$_$k$H!"e(B
range_step
rb_iterate(str_step, (VALUE)args, step_i, (VALUE)iter);
rb_iterate(VALUE (*it_proc) (VALUE), VALUE data1,
VALUE (*bl_proc) (ANYARGS), VALUE data2)
NODE *node = NEW_IFUNC(bl_proc, data2);
blockptr->iseq = (void *)node;
th->passed_block = blockptr;
retval = (*it_proc) (data1);
…
th_call0(rb_thread_t *th, VALUE klass, VALUE recv,
VALUE id, ID oid, int argc, const VALUE *argv,
NODE * body, int nosuper)
if (th->passed_block) {
blockptr = th->passed_block;
th->passed_block = 0;
}
push_frame(th, 0, FRAME_MAGIC_CFUNC,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
e$B$H$J$j!"e(Bbl_proc
e$B$,%U%l!<%`$K@Q$^$l$F$$$k$h$&$K8+$($F!"8F$P$l$F$O$$$J$$!)e(B
e$B$I$&$b40A4$Ke(B rb_iterate e$B$,5!G=$7$F$$$J$$5$$,$9$k$N$G$9$,!#e(B
e$B$H$j$"$($:$Oe(B str_step e$B$re(B rb_str_upto e$B$He(B step_i
e$B$rAH$9g$o$;$k$N$G$J$/!"e(B
rb_str_step e$B$r;H$&$h$&$K$7$F$$k$H$+$I$&$G$7$g$&!#e(B
Index: string.c
— string.c (revision 12561)
+++ string.c (working copy)
@@ -1575,7 +1575,38 @@
return beg;
}
+VALUE
+rb_str_step(VALUE beg, VALUE end, int excl, int unit)
+{
-
VALUE current, after_end;
-
ID succ = rb_intern(“succ”);
-
int n;
-
int iter = 1;
-
StringValue(end);
-
n = rb_str_cmp(beg, end);
-
if (n > 0 || (excl && n == 0)) return beg;
-
after_end = rb_funcall(end, succ, 0, 0);
-
current = beg;
-
while (!rb_str_equal(current, after_end)) {
-
iter–;
-
if (iter == 0) {
-
iter = unit;
-
rb_yield(current);
-
}
-
if (!excl && rb_str_equal(current, end)) break;
-
current = rb_funcall(current, succ, 0, 0);
-
StringValue(current);
-
if (excl && rb_str_equal(current, end)) break;
-
StringValue(current);
-
if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current)
== 0)
-
break;
-
}
-
-
return beg;
+}
-
-
/*
Index: range.c
— range.c (revision 12561)
+++ range.c (working copy)
@@ -223,7 +223,7 @@
{
VALUE *args = (VALUE *)arg;
- return rb_str_upto(args[0], args[1], EXCL(args[2]));
- return rb_str_step(args[0], args[1], EXCL(args[2]), args[3]);
}
static void
@@ -330,9 +330,8 @@
args[0] = b;
args[1] = e;
args[2] = range;