StopIteration#result

StopIteration#result e$B$r?7@_$9$k$N$O$I$&$G$7$g$&e(B?

e$B0J2<$NNc$G!"e(BStopIteration#result e$B$O!"e(B(e$B%V%m%C%/$D$-$Ne(B)
Array#each e$B$NJV$jCM$rJV$7$^$9!#e(B

a = [1,2,3]
e = a.enum_for(:each)
p e.next #=> 1
p e.next #=> 2
p e.next #=> 3
e.next rescue p $!.result #=> [1, 2, 3]

Array#each e$B$O$=$NG[Ns<+BN$rJV$9$N$G!"e(B$!.result e$B$Oe(B [1, 2, 3]
e$B$K$J$C$F$$$^$9!#e(B

Enumerator e$B$G30It%$%F%l!<%?$r:n$C$F;H$&$H!"FbIt%$%F%l!<%?$re(B
Fiber e$BFb$GF0$+$7$^$9!#e(Beach e$B$J$I$NFbIt%$%F%l!<%?$O=*N;$9$k$He(B
e$B$-$K2?$+CM$rJV$9$o$1$G$9$,!“8=:_$O$=$NCM$rF@$kJ}K!$,$”$j$^$;e(B
e$B$s!#e(B

e$B$^$!!"D>@\2?$+$KLr$KN)$D$+$H$$$&$H5?$o$7$$5$$,$7$^$9$,!“30Ite(B
e$B%$%F%l!<%?$r;H$C$FFbIt%$%F%l!<%?$r<BAu$9$k$H$-$K8e<T$NJV$jCMe(B
e$B$rA0<T$+$i;XDj$G$-$k$H$+!”$A$g$C$H%a%?$J$3$H$r$d$m$&$H$7$?$He(B
e$B$-$K;H$($k5$$,$7$^$9!#e(B

StopIteration#result e$B$O30It%$%F%l!<%?$HFbIt%$%F%l!<%?$N5!G=e(B
e$B$N$:$l$r=|5n$9$k!"$H$b$$$($^$9!#40A4@-$H$$$&$+!#e(B

e$B$H$$$&$o$1$G$I$&$G$7$g$&$+!#e(B

% svn diff --diff-cmd diff -x ‘-u -p’
Index: enumerator.c

— enumerator.c (revision 24578)
+++ enumerator.c (working copy)
@@ -33,7 +33,7 @@ struct enumerator {
VALUE fib;
VALUE dst;
VALUE lookahead;

  • VALUE no_next;
  • VALUE stop_exc;
    };

static VALUE rb_cGenerator, rb_cYielder;
@@ -284,7 +284,7 @@ enumerator_init(VALUE enum_obj, VALUE ob
ptr->fib = 0;
ptr->dst = Qnil;
ptr->lookahead = Qundef;

  • ptr->no_next = Qfalse;
  • ptr->stop_exc = Qfalse;

    return enum_obj;
    }
    @@ -506,14 +506,23 @@ next_ii(VALUE i, VALUE obj, int argc, VA
    return Qnil;
    }

+static VALUE
+stop_result(VALUE self)
+{

  • return rb_attr_get(self, rb_intern(“result”));
    +}

static VALUE
next_i(VALUE curr, VALUE obj)
{
struct enumerator *e = enumerator_ptr(obj);
VALUE nil = Qnil;

  • VALUE result;
  • rb_block_call(obj, id_each, 0, 0, next_ii, obj);
  • e->no_next = Qtrue;
  • result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
  • e->stop_exc = rb_exc_new2(rb_eStopIteration, “iteration reached at
    end”);
  • rb_ivar_set(e->stop_exc, rb_intern(“result”), result);
    return rb_fiber_yield(1, &nil);
    }

@@ -552,8 +561,8 @@ enumerator_next(VALUE obj)
return v;
}

  • if (e->no_next)
  • rb_raise(rb_eStopIteration, “iteration reached at end”);
  • if (e->stop_exc)

  • rb_exc_raise(e->stop_exc);

    curr = rb_fiber_current();

@@ -562,11 +571,11 @@ enumerator_next(VALUE obj)
}

 v = rb_fiber_resume(e->fib, 1, &curr);
  • if (e->no_next) {
  • if (e->stop_exc) {
    e->fib = 0;
    e->dst = Qnil;
    e->lookahead = Qundef;
  • rb_raise(rb_eStopIteration, “iteration reached at end”);
  • rb_exc_raise(e->stop_exc);
    }
    return v;
    }
    @@ -617,7 +626,7 @@ enumerator_rewind(VALUE obj)
    e->fib = 0;
    e->dst = Qnil;
    e->lookahead = Qundef;
  • e->no_next = Qfalse;
  • e->stop_exc = Qfalse;
    return obj;
    }

@@ -915,6 +924,7 @@ Init_Enumerator(void)
rb_define_method(rb_cEnumerator, “inspect”, enumerator_inspect, 0);

 rb_eStopIteration = rb_define_class("StopIteration", 

rb_eIndexError);

  • rb_define_method(rb_eStopIteration, “result”, stop_result, 0);

    /* Generator */
    rb_cGenerator = rb_define_class_under(rb_cEnumerator, “Generator”,
    rb_cObject);
    Index: test/ruby/test_enumerator.rb
    ===================================================================
    — test/ruby/test_enumerator.rb (revision 24578)
    +++ test/ruby/test_enumerator.rb (working copy)
    @@ -152,5 +152,14 @@ class TestEnumerator < Test::Unit::TestC
    assert_raise(StopIteration) { e.next }
    assert_raise(StopIteration) { e.next }
    end

  • def test_stop_result

  • a = [1]

  • res = a.each {}

  • e = a.each

  • assert_equal(1, e.next)

  • exc = assert_raise(StopIteration) { e.next }

  • assert_equal(res, exc.result)

  • end
    end

In article [email protected],
Tanaka A. [email protected] writes:

StopIteration#result e$B$O30It%$%F%l!<%?$HFbIt%$%F%l!<%?$N5!G=e(B
e$B$N$:$l$r=|5n$9$k!"$H$b$$$($^$9!#40A4@-$H$$$&$+!#e(B

e$B1sF#$5$s$K$$$o$l$F5$$,$D$$$?$s$G$9$,!"e(Byield e$B$NJV$jCM$r;XDj$Ge(B
e$B$-$J$$$s$G!"5!G=$N$:$l$O$^$@;D$j$^$9$M!#e(B

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

In message “Re: [ruby-dev:39115] Re: StopIteration#result”
on Wed, 19 Aug 2009 01:40:07 +0900, Tanaka A. [email protected]
writes:

|e$B1sF#$5$s$K$$$o$l$F5$$,$D$$$?$s$G$9$,!"e(Byield e$B$NJV$jCM$r;XDj$Ge(B
|e$B$-$J$$$s$G!"5!G=$N$:$l$O$^$@;D$j$^$9$M!#e(B

Pythone$B$Ne(Biteratore$B$K$Oe(Bsende$B$H$+e(Bthrowe$B$H$+$,$"$C$Fe(Byielde$B$NJV$jCM$re(B
e$B;XDj$G$-$k$h$&$K$J$C$F$^$9$Me(B(PEP-0342)e$B!#BP1~$9$ke(Byielde$B$,$J$$:Ge(B
e$B=i$Ne(B1e$B2sL$O$I$&$9$k$s$@$m$&$+$H;W$C$?$ie(BTypeErrore$B$@$=$&$G$9!#e(B

e$B$3$l$HF1$8J}?K$G$$$$$J$i!“e(Bnexte$B$K0z?t$rM?$($k$H$$$&0F$,0JA0$Ke(B
e$B=P$F$$$^$7$?$M!#$?$@!“A0$K9M$($?;~$K$O<BAu$,$+$J$jLLE]$@$C$?e(B
e$B$N$G$”$-$i$a$?$h$&$J3P$($,$”$j$^$9!#e(B

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

In message “Re: [ruby-dev:39123] Re: StopIteration#result”
on Wed, 19 Aug 2009 12:09:59 +0900, Tanaka A. [email protected]
writes:

|peek e$B$NF3F~$N7k2L!"6qBNE*$Ke(B fiber e$B$r:F5/F0$9$k$N$O!"e(Bpeek e$B$+e(B
|e$B$b$7$l$J$/$F!"e(Bnext e$B$O@hFI$_$7$?$b$N$rC1$KJV$9$@$1$+$b$7$l$^e(B
|e$B$;$s!#$=$N>l9g!“e(Bnext e$B$N0z?t$KEO$5$l$F$b<jCY$l$G$9!#e(B
|
|peek e$B$O6qBNE*$KMQES$,$”$k$N$G!"e(Byield e$B$NCM$N$h$&$K0lCJ%a%?$Je(B
|e$B$b$N$HHf$Y$k$H!"e(Bpeek e$B$,M%@h$+$J$!!#e(B

e$B$G$7$g$&$M!#e(B

|e$B1sF#$5$s$,e(B [ruby-dev:31798] e$B$Ge(B Enumerator#value= e$B$rDs0F$7$Fe(B
|e$B$^$9$,!“<!$Ke(B yield e$B$NCM$r@_Dj$9$ke(B Enumerator e$B$N%a%=%C%I$H$$e(B
|e$B$&$N$O$”$jF@$k$+$b$7$l$^$;$s!#e(Bvalue= e$B$H$$$&L>A0$O%@%a$@$H;We(B
|e$B$$$^$9$,!#e(B

Pythone$B$+$i$$$?$@$$$F!“e(Bsende$B$H$$$&$N$O$I$&$G$7$g$&!#e(BPythone$B$G$Oe(B
e$BCM$rEO$9$N$HF@$k$N$,F1$8%a%=%C%I$K$J$C$F$$$^$9$,!“e(BRubye$B$G$OJ,e(B
e$BN%$9$k$H$$$&$3$H$G!#$”$”!“$G$be(B send
e$B$Oe(BRubye$BE*$K$OLLE]$JL>A0$+e(B
e$B$J$”!#e(B__send__e$B$,$"$k$H$O$$$(!#e(B

In article [email protected],
Yukihiro M. [email protected] writes:

Pythone$B$Ne(Biteratore$B$K$Oe(Bsende$B$H$+e(Bthrowe$B$H$+$,$"$C$Fe(Byielde$B$NJV$jCM$re(B
e$B;XDj$G$-$k$h$&$K$J$C$F$^$9$Me(B(PEP-0342)e$B!#BP1~$9$ke(Byielde$B$,$J$$:Ge(B
e$B=i$Ne(B1e$B2sL$O$I$&$9$k$s$@$m$&$+$H;W$C$?$ie(BTypeErrore$B$@$=$&$G$9!#e(B

e$B$J$k$[$I!#e(B

e$B$3$l$HF1$8J}?K$G$$$$$J$i!“e(Bnexte$B$K0z?t$rM?$($k$H$$$&0F$,0JA0$Ke(B
e$B=P$F$$$^$7$?$M!#$?$@!“A0$K9M$($?;~$K$O<BAu$,$+$J$jLLE]$@$C$?e(B
e$B$N$G$”$-$i$a$?$h$&$J3P$($,$”$j$^$9!#e(B

e$B:#$Oe(B Enumerator#peek e$B$,$"$k$N$Ge(B next
e$B$N0z?t$O$&$^$/$J$$$G$9e(B
e$B$M!#e(B

peek e$B$NF3F~$N7k2L!"6qBNE*$Ke(B fiber e$B$r:F5/F0$9$k$N$O!"e(Bpeek
e$B$+e(B
e$B$b$7$l$J$/$F!"e(Bnext e$B$O@hFI$_$7$?$b$N$rC1$KJV$9$@$1$+$b$7$l$^e(B
e$B$;$s!#$=$N>l9g!"e(Bnext e$B$N0z?t$KEO$5$l$F$b<jCY$l$G$9!#e(B

peek e$B$O6qBNE*$KMQES$,$"$k$N$G!"e(Byield e$B$NCM$N$h$&$K0lCJ%a%?$Je(B
e$B$b$N$HHf$Y$k$H!"e(Bpeek e$B$,M%@h$+$J$!!#e(B

e$B1sF#$5$s$,e(B [ruby-dev:31798] e$B$Ge(B Enumerator#value=
e$B$rDs0F$7$Fe(B
e$B$^$9$,!“<!$Ke(B yield e$B$NCM$r@_Dj$9$ke(B Enumerator
e$B$N%a%=%C%I$H$$e(B
e$B$&$N$O$”$jF@$k$+$b$7$l$^$;$s!#e(Bvalue= e$B$H$$$&L>A0$O%@%a$@$H;We(B
e$B$$$^$9$,!#e(B

(e$B$=$3$G$O!“e(BEnumerator#result e$B$bDs0F$5$l$F$$$^$9$,!”$3$l$Oe(B
StopIteration#result e$B$N$[$&$,$$$$$H;W$&e(B)

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

In message “Re: [ruby-dev:39125] Re: StopIteration#result”
on Wed, 19 Aug 2009 13:07:56 +0900, Tanaka A. [email protected]
writes:

|> Pythone$B$+$i$$$?$@$$$F!“e(Bsende$B$H$$$&$N$O$I$&$G$7$g$&!#e(BPythone$B$G$Oe(B
|> e$BCM$rEO$9$N$HF@$k$N$,F1$8%a%=%C%I$K$J$C$F$$$^$9$,!“e(BRubye$B$G$OJ,e(B
|> e$BN%$9$k$H$$$&$3$H$G!#$”$”!“$G$be(B send e$B$Oe(BRubye$BE*$K$OLLE]$JL>A0$+e(B
|> e$B$J$”!#e(B__send__e$B$,$"$k$H$O$$$(!#e(B
|
|e$B$&$%$`!#e(Bsend e$B$H$$$&L>A0$O=E$J$C$F$$$k$N$G2DG=$J$iHr$1$?$$$He(B
|e$B$3$m$G$9!#e(B

PEP432e$B$K$Oe(B feed e$B$H$$$&L>A0$NDs0F$,$“$C$?$H=q$$$F$”$j$^$9!#e(B
feede$B$H$$$&$N$O0-$/$J$$$+$b$7$l$^$;$s$M!#FC$K:#2s$N0F$G$O!"M?e(B
e$B$($ke(B(feed)e$B$@$1$GJV$jCM$Oe(Bnexte$B$G<u$1$k$o$1$G$9$+$i!#e(B

|e$B$&$%$`!#e(Be.next e$B$,C1CM$J$N$,$h$m$7$/$“$j$^$;$s$J!#JV$jCM$K$9e(B
|e$B$k$H$-$K$R$H$D$NCM$K$^$H$^$C$F!”>pJs$,Mn$A$F$$$^$9!#e(B

|e$B$^$!!">o$KG[Ns$rJV$9e(B Enumerator#{next_values,peek_values} e$B$Ne(B
|e$BDI2C$G$9$+$M!#e(B

e$B$J$k$[$I!"B?CM$OFq$7$$$G$9$M$(e(B(e$B$*A0$,8@$&$+e(B)e$B!#e(B
e$BDI2C$K;?@.$7$^$9!#e(B

In article [email protected],
Yukihiro M. [email protected] writes:

Pythone$B$+$i$$$?$@$$$F!“e(Bsende$B$H$$$&$N$O$I$&$G$7$g$&!#e(BPythone$B$G$Oe(B
e$BCM$rEO$9$N$HF@$k$N$,F1$8%a%=%C%I$K$J$C$F$$$^$9$,!“e(BRubye$B$G$OJ,e(B
e$BN%$9$k$H$$$&$3$H$G!#$”$”!“$G$be(B send e$B$Oe(BRubye$BE*$K$OLLE]$JL>A0$+e(B
e$B$J$”!#e(B__send__e$B$,$"$k$H$O$$$(!#e(B

e$B$&$%$`!#e(Bsend e$B$H$$$&L>A0$O=E$J$C$F$$$k$N$G2DG=$J$iHr$1$?$$$He(B
e$B$3$m$G$9!#e(B

e$B$?$a$7$K30It%$%F%l!<%?$GFbIt%$%F%l!<%?$r<B8=$9$k$N$r=q$$$F$_e(B
e$B$k$HNc$($P$3$&$J$j$^$9!#e(B

def each_by_extiter(e)
while true
begin
v = e.next
rescue StopIteration
return $!.result
end
yield_value = yield v
# e.send v
end
end
a = [1,2,3]
e = a.each
p each_by_extiter(e) {|x| p x }

e$B$&$%$`!#e(Be.next e$B$,C1CM$J$N$,$h$m$7$/$“$j$^$;$s$J!#JV$jCM$K$9e(B
e$B$k$H$-$K$R$H$D$NCM$K$^$H$^$C$F!”>pJs$,Mn$A$F$$$^$9!#e(B

o = Object.new
def o.each
yield 1,2
end
o.each {|*x| p x } #=> [1, 2]
e = o.enum_for(:each)
each_by_extiter(e) {|*x| p x } #=> [[1, 2]]

e$B$H$$$&$h$&$K$9$k$H!"0c$$$,$o$+$j$^$9!#e(B

e$B$^$!!">o$KG[Ns$rJV$9e(B Enumerator#{next_values,peek_values} e$B$Ne(B
e$BDI2C$G$9$+$M!#e(B

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

In message “Re: [ruby-dev:39109] StopIteration#result”
on Wed, 19 Aug 2009 00:55:57 +0900, Tanaka A. [email protected]
writes:

|StopIteration#result e$B$r?7@_$9$k$N$O$I$&$G$7$g$&e(B?

e$B$3$l$K$D$$$F0U8+$rI=L@$7$F$$$^$;$s$G$7$?$,!"DI2C$K;?@.$G$9!#e(B

In article [email protected],
Yukihiro M. [email protected] writes:

|e$B$^$!!">o$KG[Ns$rJV$9e(B Enumerator#{next_values,peek_values} e$B$Ne(B
|e$BDI2C$G$9$+$M!#e(B

e$B$J$k$[$I!"B?CM$OFq$7$$$G$9$M$(e(B(e$B$*A0$,8@$&$+e(B)e$B!#e(B
e$BDI2C$K;?@.$7$^$9!#e(B

e$BB?CM$,I,MW$J$N$Oe(B
yield 1, 2
yield [1, 2]
e$B$r6hJL$7$?$$$+$i$G!“$=$N$?$a$K$=$l$i$,:.$8$C$F$7$^$&e(B next e$B$He(B
e$B$OJL$K!”>o$KG[Ns$rJV$7$F6hJL$G$-$ke(B next_values e$B$rF3F~$7$?$oe(B
e$B$1$G$9$,!“$=$l$+$iN`?d$9$k$H!“e(B
return 1, 2
return [1, 2]
e$B$r6hJL$7$?$$$J$i!”$=$l$i$,:.$8$C$F$7$^$&IaDL$N%a%=%C%I8F$S=Pe(B
e$B$7$H$OJL$K!”>o$KG[Ns$rJV$7$F6hJL$G$-$k%a%=%C%I8F$S=P$7$N7A<0e(B
e$B$rMQ0U$9$k$H$$$&J}K!$,$"$k$N$+$b$7$l$^$;$s!#e(B
obj.values_send(meth, args…) e$B$H$+!#e(B

e$B$^$!!"K\Ev$K$d$k$s$J$i!“2?$N$?$a$KJV$jCM$rB?CM$K$9$k$N$+!”$He(B
e$B$$$&E@$r9M$($F$+$i$K$9$k$Y$-$@$H;W$$$^$9$,!#e(B

callcc e$B$Ne(B k.call e$B$+$i$N>pJs$,Mn$A$k$H$$$&$@$1$J$i!"e(Bcall
e$B$K$Oe(B
e$B%V%m%C%/$,$D$1$i$l$k$H$+IT==J,$@$7e(B… (e$B$b$A$m$s$=$b$=$be(B
callcc e$B$O4+$a$i$l$J$$$7e(B)

In article [email protected],
Yukihiro M. [email protected] writes:

PEP432e$B$K$Oe(B feed e$B$H$$$&L>A0$NDs0F$,$“$C$?$H=q$$$F$”$j$^$9!#e(B
feede$B$H$$$&$N$O0-$/$J$$$+$b$7$l$^$;$s$M!#FC$K:#2s$N0F$G$O!"M?e(B
e$B$($ke(B(feed)e$B$@$1$GJV$jCM$Oe(Bnexte$B$G<u$1$k$o$1$G$9$+$i!#e(B

feed e$B$O$$$$$G$9$M!#$=$&$7$F$_$^$7$?!#e(B

e$B$H$$$&$o$1$G!"e(B

def ext_each(e)
while true
begin
vs = e.next_values
rescue StopIteration
return $!.result
end
y = yield *vs
e.feed y
end
end

e$B$H$$$&$h$&$K30It%$%F%l!<%?$r;H$C$FFbIt%$%F%l!<%?$r<BAu$7$F!"e(B
yield e$B$NCM$d%$%F%l!<%?$NCM$rF1$8$K$9$k$3$H$,$G$-$k$h$&$K$J$je(B
e$B$^$7$?!#e(B

o = Object.new
def o.each
p yield
p yield 1
p yield(1, 2)
3
end

p o.each {|*x| p x; [:b, *x] }
#=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3

p ext_each(o.to_enum) {|*x| p x; [:b, *x] }
#=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3