superclass=Object
type=class
library=_builtin
extended=
included=

ノンプリエンプティブな軽量スレッド(以下ファイバーと呼ぶ)を提供します。
他の言語では coroutine あるいは semicoroutine と呼ばれることもあります。
[[c:Thread]] と違いユーザレベルスレッドとして実装されています。

[[c:Thread]] クラスが表すスレッドと違い、明示的に指定しない限り
ファイバーのコンテキストは切り替わりません。
またファイバーは親子関係を持ちます。Fiber#resume を呼んだファイバーが親になり
呼ばれたファイバーが子になります。親子関係を壊すような遷移(例えば
自分の親の親のファイバーへ切り替えるような処理)はできません。
例外 FiberError が発生します。
できることは 
 * Fiber#resume により子へコンテキストを切り替える
 * Fiber.yield により親へコンテキストを切り替える
の二通りです。この親子関係は動的なものであり
親ファイバーへコンテキストを切り替えた時点で解消されます。

なお標準添付ライブラリ [[lib:fiber]] を require することにより、
コンテキストの切り替えに制限のない [[m:Fiber#transfer]] が使えるようになります。
任意のファイバーにコンテキストを切り替えることができます。

ファイバーが終了するとその親にコンテキストが切り替わります。

=== 例外

ファイバー実行中に例外が発生した場合、親ファイバーに例外が伝播します。

例:
 f = Fiber.new do
   raise StandardError, "hoge"
 end
 
 begin
   f.resume     # ここでも StandardError が発生する。
 rescue => e
   p e.message  #=> "hoge"
 end

=== ショートチュートリアル

ファイバーは処理のあるポイントで他のルーチンにコンテキストを切り替え、またそのポイントから再開する
という目的のために使います。
[[m:Fiber.new]] により与えられたブロックとともにファイバーを生成します。
生成したファイバーに対して [[m:Fiber#resume]] を呼ぶことによりコンテキストを切り替えます。
子ファイバーのブロック中で [[m:Fiber.yield]] を呼ぶと親にコンテキストを切り替えます。
Fiber.yield の引数が、親での Fiber#resume の返り値になります。
 f = Fiber.new do
   n = 0
   loop do
     Fiber.yield(n)
     n += 1
   end
 end
 
 5.times do
  p f.resume
 end
 
 #=> 0
     1
     2
     3
     4

以下は内部イテレータを外部イテレータに変換する例です。
実際 [[c:Enumerator]] は Fiber を用いて実装されています。

 def enum2gen(enum)
   Fiber.new do
     enum.each{|i|
       Fiber.yield(i)
     }
   end
 end
 
 g = enum2gen(1..100)
 
 p g.resume  #=> 1
 p g.resume  #=> 2
 p g.resume  #=> 3

=== 注意

Thread クラスが表すスレッド間をまたがるファイバーの切り替えはできません。
例外 FiberError が発生します。

 f = nil
 Thread.new do
   f = Fiber.new{}
 end.join
 f.resume
 #=> t.rb:5:in `resume': fiber called across threads (FiberError)
        from t.rb:5:in `<main>'
