More Related Content
More from Kindai University
More from Kindai University (20)
Ruby1.9のfiberのかっこいい使い方
- 12. ωマインドの関数定義 λを使うことがωマインドの例 -> x { ... } 階乗の再帰的定義 fact = -> n {n==0 ? 1 : n*fact[n-1]} ★下のように書く方が Ruby っぽいけど fact = -> x {(1..x).reduce(:*)}
- 13. ω+ωマインドの関数定義 λを二つ使うとω+ω -> x { -> y {...} } 組み合わせ関数(再帰なのですっごく遅い) combi=->n{->r{r==1 ?n:(n==r ?1:combi[n-1][r-1]+combi[n-1][r])}}
- 16. 関数のメモ化 関数には時間の概念がない でも、もう一つ上のωの視点から見おろせば状態が作れる 組み合わせ関数のメモ化 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}}
- 17. Fiber f=Fiber.new{|x| puts '最初' Fiber.yield puts x y=Fiber.yield puts y } > f.resume 3 #new メソッドへ 最初 => nil > f.resume #yield メソッドへ 3 => nil > f.resume7 #yield メソッドへ 7 => nil > f.resume FiberError: dead fiber called 継続、軽量スレッド Fiber.new {|x|...} ファイバーの生成 Fiver.yield(obj) 親のコンテクストに行く resume(obj) メソッド 子供のコンテクストに行く (途中でとまっていた処理を継続)
- 18. 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} 1 2 3 4 5 => 5
- 19. 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]} 0 1 1 2 3 => 5 もっとHaskellチックにこんなのもいいかも! deff.take(n) n.times {puts self.resume} end > f.take 10
- 21. Fiberによるコルーチンで軽量イベント駆動マシン Rails 3.2 からPjaxが標準に WebサーバにFiberプールで軽量スレッド メモリ節約、起動/再起動の高速化 コルーチン コルーチン Pjax ブラウザ コルーチン コルーチン 操作による イベント Fiber対応Webサーバ unicornとかGoliathとか コルーチン ブラウザへの 表示変更