Ruby1.9のFiberとクロージャのかっこいい使い方Rubyist九州山崎重一郎
まず、関数、クロージャ、継続の気持ちを説明してみますマインドRubyではどうなっているのか?          
関数とマインド関数はいつも上から目線 自分自身の心が行っていることを幽体離脱して外から眺める感じああしてこうしてこうなったらこうして関数の定義
0マインド「何もない」状態を考えてみましょう0 = φ = {}{}
1マインド「何もない」と思っている自分を見ている自分 1 = {φ}{}
2マインド1マインドの自分を見ている自分 2 = {φ,{φ}}
3マインド2マインドの自分を見ている自分 3 = {φ,{φ},{φ,{φ}}}
ωマインドこれってずっと無限にできるよねと思っている自分 ω = {φ,{φ},{φ,{φ}},...}... 「我はαでありωである」     ヨハネの黙示録
ω+1マインド「これってずっと無限にできるよねと思っている自分」を見ている自分 ω+1 = {ω}
ω+ωマインドωマインドを対象にした対象化もまた無限にできるよねと思っている自分 ω+1 = {ω,{ω},{ω,{ω}},...}...
まだまだ3ωマインドω×ωマインドωωマインド....★でも、ずっとずっとやると精神を病みます
ωマインドの関数定義λを使うことがωマインドの例-> x { ... }階乗の再帰的定義fact = -> n {n==0 ? 1 : n*fact[n-1]}★下のように書く方が Ruby っぽいけどfact = -> x {(1..x).reduce(:*)}
ω+ωマインドの関数定義λを二つ使うとω+ω-> x { -> y {...} }組み合わせ関数(再帰なのですっごく遅い)combi=->n{->r{r==1 ?n:(n==r ?1:combi[n-1][r-1]+combi[n-1][r])}}
でも有限のマインドも大切クロージャ:上から目線でつくった状態ωマインドの視点から -> nマインド(状態)を見るファイバー:継続、ジェネレータジェネレータ: n マインドから ωマインドを見る その逆も
関数とクロージャ関数の独立変数と係数 f(x) = a*x aは係数でxは独立変数?係数のa をω+ωの視点から見下ろして定義fa= ->a {->x {a*x}}で、aに何かの値を束縛したωな関数をつくる fa= ->a {->x {a*x}}> f=fa[2]> f[3]=> 6> eval('a',f.binding)=> 2
関数のメモ化関数には時間の概念がないでも、もう一つ上のωの視点から見おろせば状態が作れる組み合わせ関数のメモ化combi_memo= ->m { ->n {m[n]||={}; ->r {m[n][r]||=combi[n][r]}}}> cm=combi_memo[{}]> cm[3][2]=> 3> cm[30][7]=> 2035800> eval('m',cm.binding)=> {3=>{2=>3}, 30=>{7=>2035800}}
Fiber f=Fiber.new{|x|puts '最初'Fiber.yield      puts xy=Fiber.yield      puts y}> f.resume 3  #new メソッドへ最初=> nil> f.resume    #yield メソッドへ3=> nil> f.resume7    #yield メソッドへ7=> nil> f.resumeFiberError: dead fiber called継続、軽量スレッドFiber.new {|x|...}ファイバーの生成Fiver.yield(obj)親のコンテクストに行くresume(obj) メソッド子供のコンテクストに行く(途中でとまっていた処理を継続)
Fiber によるジェネレータnマインドとωマインドを行き来する無限ループでデータを無限に生成するプログラムの最初のn要素自然数ジェネレータnum= -> a {loop {a+=1}}> num[0]... 無限ループ〜無限集合を素直に生成しているんだけどねファイバーにした自然数ジェネレータn = Fiber.new{|a|loop{Fiber.yielda+=1}}無限集合の最初の5個だけ取り出す(Haskellみたいでかっこいい!)> 5.times {puts n.resume 0}12345=> 5
Fiber によるジェネレータフィボナッチ数列バージョン!フィボナッチ数列ジェネレータfib = -> x {a,b=x         loop {a; a,b=b,a+b}}>fib[[0,1]]... 無限ループ〜フィボナッチ数列を素直に生成しているファイバーにしたフィボナッチ数列ジェネレータf = Fiber.new{|x| a,b=x   loop {Fiber.yielda; a,b=b,a+b}}無限集合の最初の5個だけ取り出す> 5.times {puts f.resume [0,1]}01123=> 5もっとHaskellチックにこんなのもいいかも!deff.take(n) n.times {puts self.resume} end> f.take 10
Fiberによるコルーチンで軽量イベント駆動マシン初期のMacintosh OS多数のコルーチンの集合体でできていた(すっごく軽量なスレッドみたいなもの)Macintosh 128K8MHz128Kbコルーチンコルーチンコルーチンコルーチン操作によるイベント実際のメモリコルーチンビットマップへの表示など
Fiberによるコルーチンで軽量イベント駆動マシンRails 3.2 からPjaxが標準にWebサーバにFiberプールで軽量スレッドメモリ節約、起動/再起動の高速化コルーチンコルーチンPjaxブラウザコルーチンコルーチン操作によるイベントFiber対応WebサーバunicornとかGoliathとかコルーチンブラウザへの表示変更
FiberとThreadの比較出典:Ruby Fibers Vs Ruby Threadshttp://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html
Fiberによるリアルタイム処理次回にね!

Ruby1.9のfiberのかっこいい使い方