< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事(自分と同じ返事先を持つ)
N :次の記事
|<:スレッドの先頭
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
遠藤です。
> いろいろと Fiber の仕様を悩んでいたんですが,決めました.で,実装
> してコミットしました.
お疲れ様です。面白いものをありがとうございます。
さっそく遊んでみたのですが、残念ながらコルーチンとセミコルーチンは
相性が悪いことに気がついてしまいました。
Fiber の中で Fiber::Core を終わらせると、その時点で実行中だった
Fiber が「生きながら永遠に実行されない?」状態になります。
f = Fiber.new do
Fiber::Core.new { }.transfer
p 1 # ここは永遠に実行されない?
end
f.resume
f.transfer
f.resume #=> double resume (FiberError)
要するに、「Fiber をネストしたら変なことになる」という問題が「Fiber の
中で Fiber::Core を使うと変なことになる」に変わったようです。
例えば Generator の中で Fiber::Core に transfer すると、Generator から
next を取ろうとするしたとき変なことになります。
def (o = Object.new).foo
yield 1
yield 2
yield 3
Fiber::Core.new { }.transfer
end
g = o.to_enum(:foo)
p g.next #=> 1
p g.next #=> 2
p g.next #=> nil (?)
p g.next #=> double resume (FiberError) (??)
解決の方針をいくつか考えてみました。
- Fiber::Core をなくす
- Fiber::Core の終了時の戻り先を root fiber 以外にする (じゃあどこ?)
- Fiber::Core を呼び出せるのは root fiber だけ、にする (不便そう)
- Fiber::Core は callcc 並の黒魔術である、とレッテルを貼って使わせない
名称については、私は Fiber のままでもいいと思います。
Fiber や Coroutine という言葉には、ちゃんとした定義もコンセンサスも
ないようなので、はっきりいって言ったもん勝ちです。
Lua だって自分たちで "Semi"-coroutine と認めているものと Coroutine と
呼んでるわけですし。
だから短くてかっこいいのを選べばいいと思います。
おまけ。以下で落ちました。継続が呼び出せてる時点で何か間違い?
i = 0
callcc {|c| $c = c }
raise if i == 2
i += 1
Fiber::Core.new { $c.call }.transfer
--
Yusuke ENDOH <mame / tsg.ne.jp>