Enumerator with single array and multiple arguments

enumerator e$B$rDL$9$H$R$H$D$NG[Ns$HJ#?t$N0z?t$,6hJL$G$-$^$;$s!#e(B

% ./ruby -ve ’
class C
def each
yield [1,2]
yield 1,2
end
end
vs1 = []
C.new.each {|*v| vs1 << v }
p vs1

e = C.new.to_enum
vs2 = []
e.each {|*v| vs2 << v }
p vs2

ruby 1.9.0 (2007-11-21 patchlevel 0) [i686-linux]
[[[1, 2]], [1, 2]]
[[[1, 2]], [[1, 2]]]

e$B!!$5$5$@$G$9!%e(B

Tanaka A. wrote:

enumerator e$B$rDL$9$H$R$H$D$NG[Ns$HJ#?t$N0z?t$,6hJL$G$-$^$;$s!#e(B

e$B!!$3$s$J46$8$G$I$&$G$7$g$&$+!%e(Brb_iterate e$B$G@Q$`e(B C
e$B$G=q$$$?%V%m%C%/8Fe(B
e$B$S=P$74X?t$G!$e(B1.8 e$B$@$He(B self
e$B$rEO$7$F$$$?$H$3$m$r!$0z?t$N?t$rEO$9$h$&e(B
e$B$K$7$F$_$^$7$?!%C/$be(B self e$B;H$C$F$J$$$+$i$$$$$+$J$!!$$H!%e(B

Index: include/ruby/ruby.h

— include/ruby/ruby.h (e$B%j%S%8%g%se(B 14039)
+++ include/ruby/ruby.h (e$B:n6H%3%T!<e(B)
@@ -772,6 +772,7 @@
VALUE rb_each(VALUE);
VALUE rb_yield(VALUE);
VALUE rb_yield_values(int n, …);
+VALUE rb_yield_values2(int n, VALUE *argv);
VALUE rb_yield_splat(VALUE);
int rb_block_given_p(void);
void rb_need_block(void);
Index: enumerator.c

— enumerator.c (e$B%j%S%8%g%se(B 14039)
+++ enumerator.c (e$B:n6H%3%T!<e(B)
@@ -225,6 +225,17 @@
}

static VALUE
+enumerator_each_i(VALUE v, VALUE enum_obj, int argc)
+{

  • if (argc == 1) {
  • return rb_yield(v);
  • }
  • else {
  • return rb_yield_values2(argc, RARRAY_PTR(v));
  • }
    +}

+static VALUE
enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc,
VALUE *argv)
{
struct enumerator *ptr = enumerator_ptr(enum_obj);
@@ -235,7 +246,7 @@
ptr->iter = enumerator_iter_i;
}
else {

  • ptr->iter = (enum_iter *)rb_yield;
  • ptr->iter = (enum_iter *)enumerator_each_i;
    }
    if (argc) ptr->args = rb_ary_new4(argc, argv);
    ptr->fib = 0;
    Index: eval.c
    ===================================================================
    — eval.c (e$B%j%S%8%g%se(B 14039)
    +++ eval.c (e$B:n6H%3%T!<e(B)
    @@ -953,6 +953,12 @@
    }

VALUE
+rb_yield_values2(int argc, VALUE *argv)
+{

  • return rb_yield_0(argc, argv);
    +}

+VALUE
rb_yield_splat(VALUE values)
{
VALUE tmp = rb_check_array_type(values);
Index: insnhelper.ci

— insnhelper.ci (e$B%j%S%8%g%se(B 14039)
+++ insnhelper.ci (e$B:n6H%3%T!<e(B)
@@ -661,7 +661,7 @@
self, (VALUE)block->dfp,
0, th->cfp->sp, block->lfp, 1);

  • val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, Qnil);
  • val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc);

    th->cfp++;
    return val;

In article [email protected],
SASADA Koichi [email protected] writes:

e$B!!$3$s$J46$8$G$I$&$G$7$g$&$+!%e(Brb_iterate e$B$G@Q$`e(B C e$B$G=q$$$?%V%m%C%/8Fe(B
e$B$S=P$74X?t$G!$e(B1.8 e$B$@$He(B self e$B$rEO$7$F$$$?$H$3$m$r!$0z?t$N?t$rEO$9$h$&e(B
e$B$K$7$F$_$^$7$?!%C/$be(B self e$B;H$C$F$J$$$+$i$$$$$+$J$!!$$H!%e(B

yield(*[]) e$B$H$9$k$He(B to_enum e$B$G>pJs$,JQ2=$7$^$9!#e(B

% ./ruby -ve ’
class C
def each
yield(*[])
end
end
vs1 = []
C.new.each {|*v| vs1 << v }
p vs1
vs2 = []
C.new.to_enum.each {|*v| vs2 << v }
p vs2

ruby 1.9.0 (2007-11-28 patchlevel 0) [i686-linux]
[[]]
[[[]]]

v e$B$He(B argc e$B$NAH9g$;$G>pJs$rEA$($k$N$O4V0c$$$d$9$$$N$G!">o$KG[e(B
e$BNs$G$o$?$9e(B API e$B$,$$$$$N$G$O$J$$$G$7$g$&$+!#e(B

e$B!!$5$5$@$G$9!%e(B

Tanaka A. wrote:

yield(*[]) e$B$H$9$k$He(B to_enum e$B$G>pJs$,JQ2=$7$^$9!#e(B

e$B!!$9$_$^$;$s!%$3$l$O$?$@$N%P%0$G$7$?!%B>$K$bJQ$JNc$,$"$C$?$i65$($F$/e(B
e$B$@$5$$!%e(B

e$B!!$5$5$@$G$9!%e(B

Yukihiro M. wrote:

e$B$1$C$3$&NI$$%"%$%G%#%"$G$O$J$$$+$H;W$$$^$7$?!#8D?ME*$K$O4X?te(B
e$B$Ke(Bargc, argve$B$rEO$9e(Brb_block_call()e$BN`;w$N4X?t$r:n$k:n6HCf$G$7e(B
e$B$?$,!"$3$C$A$NJ}$,0\9T%3%9%H$,Dc$=$&!#e(B

e$B!!$=$l$rA@$$$^$7$?!%e(B

e$B$3$l$HF1$8$3$H$r7k6I$"$A$3$A$G$7$J$1$l$P$J$i$J$$$N$G!"$3$l$Oe(B
rb_yield_values3()e$B$H$+$$$&L>A0$Ge(Bpublice$B$K$7$F$O$I$&$G$7$g$&$+!#e(B
e$B$b$C$HNI$$L>A0$,$"$k$+$b$7$l$^$;$s$,!#e(B

e$B!!$"$A$3$A$G$7$J$$$H%@%a$G$9$+!%D/$a$F$$F!$<B$O$"$s$^$j$J$$$+$J!$$He(B
e$B;W$C$?$s$G$9$,!%$H$j$"$($:%3%
%C%H$7$F!$Bt;3;H$&$h$&$@$C$?$i4X?t2=$9e(B
e$B$k$C$F$3$H$G$$$$$G$9$+$M!%e(B

e$B!!:#$^$G$Ne(B ifunc
e$B0J>e$K$3$NMQES$G;H$o$l$k$h$&$G$7$?$i!$$^$D$b$H$5$se(B
e$B$b8@$C$F$$$k!V4X?t$Ke(Bargc,
argve$B$rEO$9e(Brb_block_call()e$BN`;w$N4X?t!W$rMQe(B
e$B0U$7$?$[$&$,NI$$$+$H;W$$$^$9!%e(B

e$B$^$?!"<B$Oe(Bargce$B$OI,MW$J$/$FC10l$NCM$+B?CMe(B(e$B$rG[Ns$K%Q%C%/$7$?e(B
e$B$b$N$+e(B)e$B6hJL$G$-$k%U%i%0$,$"$l$P$h$$$o$1$G$9$,!"$=$NJU$O$*$^e(B
e$B$+$;$7$^$9!#e(B

e$B!!:G=i$Oe(B values e$BI|3h$+!$$H$+9M$($?$s$G$9$,!$$J$+$J$+!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:32389] Re: enumerator with single array and
multiple arguments.”
on Wed, 28 Nov 2007 14:54:45 +0900, SASADA Koichi [email protected]
writes:

|Tanaka A. wrote:
|> enumerator e$B$rDL$9$H$R$H$D$NG[Ns$HJ#?t$N0z?t$,6hJL$G$-$^$;$s!#e(B
|
|e$B!!$3$s$J46$8$G$I$&$G$7$g$&$+!%e(Brb_iterate e$B$G@Q$`e(B C e$B$G=q$$$?%V%m%C%/8Fe(B
|e$B$S=P$74X?t$G!$e(B1.8 e$B$@$He(B self e$B$rEO$7$F$$$?$H$3$m$r!$0z?t$N?t$rEO$9$h$&e(B
|e$B$K$7$F$_$^$7$?!%C/$be(B self e$B;H$C$F$J$$$+$i$$$$$+$J$!!$$H!%e(B

e$B$1$C$3$&NI$$%“%$%G%#%”$G$O$J$$$+$H;W$$$^$7$?!#8D?ME*$K$O4X?te(B
e$B$Ke(Bargc,
argve$B$rEO$9e(Brb_block_call()e$BN`;w$N4X?t$r:n$k:n6HCf$G$7e(B
e$B$?$,!"$3$C$A$NJ}$,0\9T%3%9%H$,Dc$=$&!#e(B

e$B$?$@!"e(B

| static VALUE
|+enumerator_each_i(VALUE v, VALUE enum_obj, int argc)
|+{
|+ if (argc == 1) {
|+ return rb_yield(v);
|+ }
|+ else {
|+ return rb_yield_values2(argc, RARRAY_PTR(v));
|+ }
|+}

e$B$3$l$HF1$8$3$H$r7k6I$“$A$3$A$G$7$J$1$l$P$J$i$J$$$N$G!”$3$l$Oe(B
rb_yield_values3()e$B$H$+$$$&L>A0$Ge(Bpublice$B$K$7$F$O$I$&$G$7$g$&$+!#e(B
e$B$b$C$HNI$$L>A0$,$"$k$+$b$7$l$^$;$s$,!#e(B

e$B$^$?!“<B$Oe(Bargce$B$OI,MW$J$/$FC10l$NCM$+B?CMe(B(e$B$rG[Ns$K%Q%C%/$7$?e(B
e$B$b$N$+e(B)e$B6hJL$G$-$k%U%i%0$,$”$l$P$h$$$o$1$G$9$,!"$=$NJU$O$*$^e(B
e$B$+$;$7$^$9!#e(B