e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B
e$B1sF#$5$s$+$ie(B
http://d.hatena.ne.jp/ku-ma-me/20070817/p2
e$B$G;XE&$5$l$F$$$k$N$G$9$,!“e(BEnumerator#nexte$B$NFbB&$G$5$i$Ke(B
Enumerator#nexte$B$,8F$P$l$k$H!”%(%i!<$K$J$j$^$9!#%G%P%C%,$GDI$$e(B
e$B$+$1$k$He(B rb_fiber_yield()
e$B$+$iEO$7$?CM$H0c$&$b$Ne(B(yielde$B$5$l$?e(B
e$BCM!)e(B)e$B$,5"$C$F$-$F$$$k$h$&$G$9!#e(B
def (o = Object.new).each
yield 0
p [1,2,3].to_enum.next
end
p o.to_enum.next # => double.rb:6:in `’: unhandled exception
current
fibere$B$re(Byielde$B$7$F$$$k$O$:$J$N$K!"e(BFIXNUMe$B$Ne(B0(yielde$B$7$?e(B
e$BCM!)e(B)e$B$,EO$5$l$k!#e(B0e$B$Oe(BFibere$B$G$O$J$$$N$Ge(BTypeErrore$BNc30$,H/@8$7$Fe(B
e$B$$$k!#e(B
e$B;d$Ne(BFibere$B$NCN<1$G$O$3$3$^$G$,8B3&$G$7$?!#$3$l$O%P%0$G$7$g$&e(B
e$B$+!"[email protected])8B$H$9$Y$-$G$7$g$&$+!#$G$-$l$P!"%M%9%H$G$-$J$$e(B
[email protected]$&@)8B$O$J$$J}$,$&$l$7$$$N$G$9$,!#e(B
e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)
[email protected]$G$9!#e(B
Yukihiro M. wrote:
e$B;d$Ne(BFibere$B$NCN<1$G$O$3$3$^$G$,8B3&$G$7$?!#$3$l$O%P%0$G$7$g$&e(B
e$B$+!"[email protected])8B$H$9$Y$-$G$7$g$&$+!#$G$-$l$P!"%M%9%H$G$-$J$$e(B
[email protected]$&@)8B$O$J$$J}$,$&$l$7$$$N$G$9$,!#e(B
e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)
e$B!!$3$s$J46$8$G$I$&$G$7$g$&!#$D$^$j!"%V%m%C%/$N:G8e$be(B
rb_fiber_yield
e$B$GLa$k$h$&$K$7$^$7$g$&$C$F46$8$G!#e(B
Index: enumerator.c
— enumerator.c (e$B%j%S%8%g%se(B 13113)
+++ enumerator.c (e$B:n6H%3%T!<e(B)
@@ -13,6 +13,7 @@
************************************************/
#include “ruby/ruby.h”
+#include “debug.h”
/*
- Document-class: Enumerable::Enumerator
@@ -42,6 +43,7 @@
VALUE fib;
VALUE next;
VALUE dst;
static void
@@ -237,6 +239,7 @@
if (argc) ptr->args = rb_ary_new4(argc, argv);
ptr->fib = 0;
ptr->next = ptr->dst = Qnil;
-
ptr->has_next = Qnil;
return enum_obj;
}
@@ -381,19 +384,20 @@
next_i(VALUE curr, VALUE obj)
{
struct enumerator *e = enumerator_ptr(obj);
-
e->dst = curr;
- e->dst = curr;
rb_block_call(obj, rb_intern(“each”), 0, 0, next_ii, obj);
- return e->next;
- e->has_next = Qfalse;
- rb_fiber_yield(e->dst, 1, &e->next);
}
static void
next_init(VALUE obj, struct enumerator *e)
{
VALUE curr = rb_fiber_current();
e->dst = curr;
e->fib = rb_block_call(rb_cFiber, rb_intern("new"), 0, 0,
next_i, obj);
- e->has_next = Qtrue;
rb_fiber_yield(e->fib, 1, &curr);
}
@@ -416,16 +420,18 @@
{
struct enumerator *e = enumerator_ptr(obj);
VALUE curr, v;
- curr = rb_fiber_current();
- curr = rb_fiber_current();
if (!e->fib) {
next_init(obj, e);
}
- if (!rb_fiber_alive_p(e->fib)) {
-
- if (!e->has_next) {
e->fib = 0;
e->next = e->dst = Qnil;
rb_raise(rb_eStopIteration, “Enumerator#each reached at end”);
}
- v = rb_fiber_yield(e->fib, 1, &curr);
return v;
}
@@ -441,11 +447,7 @@
enumerator_next_p(VALUE obj)
{
struct enumerator *e = enumerator_ptr(obj);
-
- if (!e->fib) {
- next_init(obj, e);
- }
- return rb_fiber_alive_p(e->fib);
/*
e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B
In message “Re: [ruby-dev:31508] Re: nested fiber invocation”
on Sun, 19 Aug 2007 21:16:13 +0900, SASADA Koichi [email protected]
writes:
|e$B!!$3$s$J46$8$G$I$&$G$7$g$&!#$D$^$j!"%V%m%C%/$N:G8e$be(B rb_fiber_yield
|e$B$GLa$k$h$&$K$7$^$7$g$&$C$F46$8$G!#e(B
e$B$$!"$A$c$s$HF0$/!#$G$b!"$I$&$7$F:#$^[email protected]$H%@%a$G!V%V%m%Ce(B
e$B%/$N:G8e$be(B rb_fiber_yield e$B$GLa$k!W$HBg>fIW$J$N$+$O$h$/$o$+$ie(B
e$B$J$$$s$G$9$1$I!#e(B
e$B$"$H!"<B:]$KFI$_9~$`A0$Ne(Bnext?e$B$,e(Bnile$B$rJV$9$s$G$9$,!"$3$l$O$"$se(B
e$B$^$j$&$l$7$/$J$$;EMMJQ99$G$9$M$(!#e(Bnext_pe$B$N<BAu$r$A$g$C$H9)IWe(B
e$B$9$l$P$h$$$N$+$7$i$s!#e(B
e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B
In message “Re: [ruby-dev:31513] Re: nested fiber invocation”
on Mon, 20 Aug 2007 11:14:53 +0900, Yukihiro M.
[email protected] writes:
|e$B$"$H!"<B:]$KFI$_9~$`A0$Ne(Bnext?e$B$,e(Bnile$B$rJV$9$s$G$9$,!"$3$l$O$"$se(B
|e$B$^$j$&$l$7$/$J$$;EMMJQ99$G$9$M$(!#e(Bnext_pe$B$N<BAu$r$A$g$C$H9)IWe(B
|e$B$9$l$P$h$$$N$+$7$i$s!#e(B
- next_pe$B$NCf$Ge(Be->fibe$B$,e([email protected]$C$?$ie(Bnext_inite$B$r8F$Ve(B
- nexte$B$NCf$GNc30H/@8A0$Ke(Be->has_nexte$B$re(Bnile$B$Ke(B
e$B$7$F$_$^$7$?!#$I$&$b4|BTDL$jF0$$$F$$$k$h$&$G$9!#$7$+$7!"<B$Oe(B
e$B8e<T$OITMW$N$h$&$G$9!#e(B
[email protected]$G$9!#e(B
Yukihiro M. wrote:
e$B$$!"$A$c$s$HF0$/!#$G$b!"$I$&$7$F:#$^[email protected]$H%@%a$G!V%V%m%Ce(B
e$B%/$N:G8e$be(B rb_fiber_yield e$B$GLa$k!W$HBg>fIW$J$N$+$O$h$/$o$+$ie(B
e$B$J$$$s$G$9$1$I!#e(B
e$B!!5U$K!"%V%m%C%/$,$=$N$^$^=*N;$7$?$i$I$&$J$k$G$7$g$&!"$H$$$&OC$G$9!#e(B
e$B5$IU$/$N$N;~4V$,[email protected]$1$I!"1sF#$5$s$O:G=i$+$i$=$l$r;XE&$7$F$$e(B
e$B$k$H$$$&!#e(B
e$B!!$D$^$j!“e(BFiber
e$B$N%V%m%C%/$,=*N;$7$?$i$I$&$J$k$+!”$H$$$&OC$J$s$G$9e(B
e$B$,!#e(BFiber
e$B$N%V%m%C%/$,=*N;$7$?$i!“Nc30!”$C$D$&$N$,$$$$$h$&$J5$$,$7$Fe(B
e$B$$$^$9!#$G$O!“2?$KNc30$rEj$2$k$N$+$C$F$N$,$^$?LLE]$J$s$G$9$,!#$&!<e(B
e$B$s!”$I$&$7$h$&!#e(B
e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B
In message “Re: [ruby-dev:31508] Re: nested fiber invocation”
on Sun, 19 Aug 2007 21:16:13 +0900, SASADA Koichi [email protected]
writes:
|e$B!!$3$s$J46$8$G$I$&$G$7$g$&!#$D$^$j!"%V%m%C%/$N:G8e$be(B rb_fiber_yield
|e$B$GLa$k$h$&$K$7$^$7$g$&$C$F46$8$G!#e(B
e$B%3%_%C%H$7$F$/[email protected]$5$$!#e(B
[email protected]$G$9!#e(B
Yukihiro M. wrote:
e$B%3%_%C%H$7$F$/[email protected]$5$$!#e(B
e$B!!$D$$$G$K%F%9%H$b%3%_%C%H$7$^$7$?!de(Btest/ruby/test_enumerator.rb
e$B!!;d$OF,$,0-$$$N$G!"$I$&$"$k$Y$-$+$9$0$KK:$l$F$7$^$$$^$9!#2?$+DI2C$7e(B
e$B$?$i%F%9%H$b$D$$$G$KDI2C$7$H$$$F$b$i$($k$H=u$+$j$^$9!#e(B
e$B!!:G6a!"EDCf$5$s$NCf$G$O%F%9%H%U%!!<%9%H!Je(BSEGVe$B$9$k%F%9%H$bFM$C9~$s$Ge(B
e$B$*$/!K$H$$$&$N$,N.9T$C$F$k$=$&$J$s$G$9$,!"[email protected]$9$k$N$rK:$l$Je(B
e$B$$!“NI$$<[email protected]$J$”$H;W$$$^$9!#e(B
[email protected]!“8D?ME*$K$O!“e(Bknown bug
e$B$G$”$k$3$H$,[email protected]$K$J$k$h$&$K!”%U%!%$%ke(B
e$B$rJ,$1$F$/$l$k$H$$$$$H;W$&[email protected]$1$I!J2r7h$7$?;[email protected]$GE,@Z$J%F%9%H%U%!%$e(B
e$B%k$X0\F0!K!#e(B
[email protected]$G$9!#e(B
e$B!!F,[email protected]}$N$?$a$K!"e(BRubye$B$G=q$$$F$_$^$7$?!#e(B
class Gen
def initialize e
@e = e
@fib = nil
end
def next?
init_next unless @fib
@has_next
end
def next
init_next unless @fib
raise “mou naiyo” unless @has_next
r = @next
@fib.yield(Fiber.current)
r
end
def rewind
@fib = nil
self
end
private
def init_next
@fib = Fiber.new{|fib|
@has_next = true
@e.each{|e|
@next = e
fib = fib.yield(e)
}
@has_next = false
fib.yield(nil)
}
@fib.yield(Fiber.current)
end
end
gen = Gen.new(3.times)
p gen.next
p gen.next
p gen.next
gen.rewind
p gen.next
e$B!!e(BFiber
e$BCf$GH/@8$7$?Nc30$r$I$3$KEAHB$5$;$k$N$+!"$d$C$Q$j$I$&$K$b$o$+e(B
e$B$i$J$$$N$G!"e(BSemiCoroutine e$B$H$7$F<[email protected]$m$&$+!#e(B